home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1999 March / EnigmA AMIGA RUN 35 (1999)(G.R. Edizioni)(IT)[!][issue 1999-03].iso / earcd / devel / vbcc-src / machines / m68k / machine.c next >
C/C++ Source or Header  |  1999-01-01  |  105KB  |  2,480 lines

  1. /*  Code generator for Motorola 680x0 CPUs. Supports 68000-68060+68881/2.   */
  2. /*  PhxAss and the GNU assembler is supported.                              */
  3.  
  4. #include "supp.h"
  5.  
  6. static char FILE_[]=__FILE__;
  7.  
  8. /*  Public data that MUST be there.                             */
  9.  
  10. /* Name and copyright. */
  11. char cg_copyright[]="vbcc code-generator for m68k V1.2 (c) in 1995-99 by Volker Barthelmann";
  12.  
  13. /*  Commandline-flags the code-generator accepts                */
  14. int g_flags[MAXGF]={VALFLAG,VALFLAG,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  15. char *g_flags_name[MAXGF]={
  16.     "cpu","fpu","d2scratch","noa4","sc","sd","prof","const-in-data",
  17.     "use-framepointer","no-addressing-modes","no-delayed-popping",
  18.     "gas","branch-opt","no-fp-return","no-mreg-return","g"};
  19.  
  20. union ppi g_flags_val[MAXGF];
  21.  
  22. /*  Alignment-requirements for all types in bytes.              */
  23. zlong align[16];
  24.  
  25. /*  Alignment that is sufficient for every object.              */
  26. zlong maxalign;
  27.  
  28. /*  CHAR_BIT of the target machine.                             */
  29. zlong char_bit;
  30.  
  31. /*  Sizes of all elementary types in bytes.                     */
  32. zlong sizetab[16];
  33.  
  34. /*  Minimum and Maximum values each type can have.              */
  35. /*  Must be initialized in init_cg().                           */
  36. zlong t_min[32];
  37. zulong t_max[32];
  38.  
  39. /*  Names of all registers.                                     */
  40. char *regnames[MAXR+1]={"noreg","a0","a1","a2","a3","a4","a5","a6","a7",
  41.                                "d0","d1","d2","d3","d4","d5","d6","d7",
  42.                         "fp0","fp1","fp2","fp3","fp4","fp5","fp6","fp7"};
  43.  
  44. /*  The Size of each register in bytes.                         */
  45. zlong regsize[MAXR+1];
  46.  
  47. /*  Type which can store each register. */
  48. struct Typ *regtype[MAXR+1];
  49.  
  50. /*  regsa[reg]!=0 if a certain register is allocated and should */
  51. /*  not be used by the compiler pass.                           */
  52. int regsa[MAXR+1]={0,0,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  53.  
  54. /*  Specifies which registers may be scratched by functions.    */
  55. int regscratch[MAXR+1]={0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,0};
  56.  
  57. /* Names of target-specific variable attributes.                */
  58. char *g_attr_name[]={"__far","__near","__chip","__saveds",0};
  59.  
  60. /****************************************/
  61. /*  Some private data and functions.    */
  62. /****************************************/
  63.  
  64. static long malign[16]=  {1,1,2,2,2,2,2,1,2,1,1,1,2,1};
  65. static long msizetab[16]={0,1,2,4,4,4,8,0,4,0,0,0,4,0};
  66.  
  67. static struct Typ ltyp={LONG},larray={ARRAY,<yp};
  68.  
  69. static char reglist[200];
  70.  
  71. #define DATA 0
  72. #define BSS 1
  73. #define CODE 2
  74.  
  75. static int reglabel,freglabel,section=-1;
  76. static char *codename,*bssname,*dataname;
  77. static char *m_bssname,*m_dataname;
  78.  
  79. static void probj2(FILE *,struct obj *,int);
  80. static struct IC *do_refs(FILE *,struct IC *);
  81. static void pr(FILE *,struct IC *);
  82. static int get_reg(FILE *,int,struct IC *);
  83. static long pof2(zulong);
  84. static void function_top(FILE *,struct Var *,long);
  85. static void function_bottom(FILE *f,struct Var *,long);
  86.  
  87. static void saveregs(FILE *,struct IC *),restoreregsa(FILE *,struct IC *);
  88. static void restoreregsd(FILE *,struct IC *);
  89.  
  90. static void assign(FILE *,struct IC *,struct obj *,struct obj *,int,long,int);
  91. static int compare_objects(struct obj *o1,struct obj *o2);
  92.  
  93. static int is_const(struct Typ *t);
  94.  
  95. static char x_s[]={'0','b','w','3','l'};
  96. static char x_t[]={'?','b','w','l','l','s','d','v','l','a','s','u','e','f','?','?'};
  97.  
  98. static char *quick[2]={"","q"};
  99. static char *strshort[2]={"l","w"};
  100.  
  101. static char *ubranch[]={"eq","ne","cs","cc","ls","hi"};
  102.  
  103. static int pushedreg,stored_cc; /* pushedreg&2: aregsaved; 4: dreg; 8: freg */
  104.                                 /* 16: durch RESTOREREGS gepushed           */
  105. static int pushlabel,pushflag;
  106. static int geta4;
  107.  
  108. #define D16OFF 1024
  109.  
  110. static int newobj=0;   /*  um zu erkennen, ob neue section erlaubt ist */
  111.  
  112. static int gas,dbout;
  113.  
  114. static int isquickkonst(union atyps *,int),isquickkonst2(union atyps *,int),regavailable(int);
  115. static void move(FILE *,struct obj *,int,struct obj *,int,int);
  116. static void add(FILE *,struct obj *,int,struct obj *,int,int);
  117. static void sub(FILE *,struct obj *,int,struct obj *,int,int);
  118. static void mult(FILE *,struct obj *,int,struct obj *,int,int,int,struct IC *);
  119.  
  120. static long pof2(zulong x)
  121. /*  Yields log2(x)+1 oder 0. */
  122. {
  123.     zulong p;int ln=1;
  124.     p=ul2zul(1L);
  125.     while(ln<=32&&zulleq(p,x)){
  126.         if(zuleqto(x,p)) return(ln);
  127.         ln++;p=zuladd(p,p);
  128.     }
  129.     return(0);
  130. }
  131.  
  132. #define isreg(x) ((p->x.flags&(REG|DREFOBJ))==REG)
  133.  
  134. #define PEA 1000
  135.  
  136. static int addressing(void);
  137. static long notpopped,dontpop,stackoffset,loff;
  138. static int offlabel,regoffset;
  139. /*  For keeping track of condition codes.   */
  140. static struct obj *cc_set,*cc_set_tst;
  141. static int cc_typ,cc_typ_tst;
  142.  
  143. static int pget_reg(FILE *f,int flag,struct IC *p)
  144. {
  145.     int i;
  146.     flag=1+flag*8;
  147.     for(i=flag;i<flag+8;i++){
  148.         if(regs[i]==1&&(!p||(i!=p->q1.reg&&i!=p->q2.reg&&i!=p->z.reg))){
  149.             if(p){
  150.                 if((p->q1.am&&(p->q1.am->dreg==i||p->q1.am->basereg==i))
  151.                  ||(p->q2.am&&(p->q2.am->dreg==i||p->q2.am->basereg==i))
  152.                  ||(p->z.am&&(p->z.am->dreg==i||p->z.am->basereg==i))){
  153.                     continue;
  154.                 }
  155.             }
  156.             regs[i]+=8;if(!pushlabel) {pushlabel=++label;pushflag=1;}
  157.             fprintf(f,"\tmove.l\t%s,l%d\n",regnames[i],pushlabel);
  158.             if(i<9) pushedreg|=2;
  159.             else if (i<17) pushedreg|=4;
  160.             else pushedreg|=8;
  161.             return(i);
  162.         }
  163.     }
  164.     ierror(0);
  165. }
  166. static int get_reg(FILE *f,int flag,struct IC *p)
  167. /*  Gets a register: flag=0=areg, 1=dreg, 2=fpreg           */
  168. {
  169.     int i;
  170.     flag=1+flag*8;
  171.     for(i=flag;i<flag+8;i++){
  172.         if(regs[i]==0){
  173.             if(p){
  174.                 if((p->q1.am&&(p->q1.am->dreg==i||p->q1.am->basereg==i))
  175.                  ||(p->q2.am&&(p->q2.am->dreg==i||p->q2.am->basereg==i))
  176.                  ||(p->z.am&&(p->z.am->dreg==i||p->z.am->basereg==i))){
  177. /*                    iwarning("%s used in get_reg(1)",regnames[i]);*/
  178.                     continue;
  179.                 }
  180.             }
  181.             regs[i]=2;pushedreg|=1;
  182.             if(!regused[i]&&!regscratch[i]){regused[i]=1; }
  183.             return(i);
  184.         }
  185.     }
  186.     for(i=flag;i<flag+8;i++){
  187.         if(regs[i]==1&&(!p||(i!=p->q1.reg&&i!=p->q2.reg&&i!=p->z.reg))){
  188.             if(p){
  189.                 if((p->q1.am&&(p->q1.am->dreg==i||p->q1.am->basereg==i))
  190.                  ||(p->q2.am&&(p->q2.am->dreg==i||p->q2.am->basereg==i))
  191.                  ||(p->z.am&&(p->z.am->dreg==i||p->z.am->basereg==i))){
  192. /*                    iwarning("%s used in get_reg(2)",regnames[i]);*/
  193.                     continue;
  194.                 }
  195.             }
  196.             regs[i]+=4;
  197.             if(i<17) {fprintf(f,"\tmove.l\t%s,-(a7)\n",regnames[i]);stackoffset-=4;}
  198.              else {fprintf(f,"\tfmove.x\t%s,-(a7)\n",regnames[i]);stackoffset-=12;}
  199. /*            if(p->code==COMPARE) ierror("corrupt code for compare generated - sorry");*/
  200.             if(i<9) pushedreg|=2;
  201.             else if (i<17) pushedreg|=4;
  202.             else pushedreg|=8;
  203.             return(i);
  204.         }
  205.     }
  206.     ierror(0);
  207. }
  208. static int isquickkonst(union atyps *p,int t)
  209. /*  Returns 1 if constant is between -128 and 127.   */
  210. {
  211.     zlong zl;zulong zul;
  212.     if((t&NQ)==FLOAT||(t&NQ)==DOUBLE) return 0;
  213.     eval_const(p,t);
  214.     if(t&UNSIGNED){
  215.         zul=ul2zul(127UL);
  216.         return(zulleq(vulong,zul));
  217.     }else{
  218.         zl=l2zl(-129L);
  219.         if(zlleq(vlong,zl)) return(0);
  220.         zl=l2zl(127L);
  221.         return(zlleq(vlong,zl));
  222.     }
  223. }
  224. static int isquickkonst2(union atyps *p,int t)
  225. /*  Returns 1 if constant is between 1 and 8.   */
  226. {
  227.     zlong zl;zulong zul;
  228.     if((t&NQ)==FLOAT||(t&NQ)==DOUBLE) return 0;
  229.     eval_const(p,t);
  230.     if(t&UNSIGNED){
  231.         if(zuleqto(ul2zul(0UL),vulong)) return(0);
  232.         zul=ul2zul(8UL);
  233.         return(zulleq(vulong,zul));
  234.     }else{
  235.         if(zleqto(l2zl(0L),vlong)) return(0);
  236.         zl=l2zl(-1L);
  237.         if(zlleq(vlong,zl)) return(0);
  238.         zl=l2zl(8L);
  239.         return(zlleq(vlong,zl));
  240.     }
  241. }
  242. static int regavailable(int art)
  243. /*  Returns true if matching register is available.     */
  244. {
  245.     int i;
  246.     art=1+art*8;
  247.     for(i=art+1;i<art+8;i++)
  248.         if(regs[i]==0) return(1);
  249.     return(0);
  250. }
  251. static int compare_objects(struct obj *o1,struct obj *o2)
  252. /*  Tests if two objects are equal.     */
  253. {
  254.     if(o1->flags==o2->flags&&o1->am==o2->am){
  255.         if(!(o1->flags&VAR)||(o1->v==o2->v&&zleqto(o1->val.vlong,o2->val.vlong))){
  256.             if(!(o1->flags®)||o1->reg==o2->reg){
  257.                 return(1);
  258.             }
  259.         }
  260.     }
  261.     return(0);
  262. }
  263. static struct IC *do_refs(FILE *f,struct IC *p)
  264. /*  Loads DREFOBJs into address registers, if necessary.    */
  265. /*  Small constants are loaded into data registers if this  */
  266. /*  improves code.                                          */
  267. {
  268.     int reg,c=p->code,t=p->typf,equal;
  269.     if((p->q1.flags&DREFOBJ)&&(!(p->q1.flags®)||p->q1.reg<1||p->q1.reg>8)){
  270.         equal=0;
  271.         if(compare_objects(&p->q1,&p->q2)) equal|=1;
  272.         if(compare_objects(&p->q1,&p->z)) equal|=2;
  273.         reg=get_reg(f,0,p);
  274.         p->q1.flags&=~DREFOBJ;
  275.         fprintf(f,"\tmove.l\t");probj2(f,&p->q1,POINTER);
  276.         p->q1.flags=REG|DREFOBJ;
  277.         p->q1.reg=reg;
  278.         fprintf(f,",%s\n",regnames[p->q1.reg]);
  279.         if(equal&1) p->q2=p->q1;
  280.         if(equal&2) p->z=p->q1;
  281.     }
  282.     if((p->q2.flags&DREFOBJ)&&(!(p->q2.flags®)||p->q2.reg<1||p->q2.reg>8)){
  283.         if(compare_objects(&p->q2,&p->z)) equal=1; else equal=0;
  284.         reg=get_reg(f,0,p);
  285.         p->q2.flags&=~DREFOBJ;
  286.         fprintf(f,"\tmove.l\t");probj2(f,&p->q2,POINTER);
  287.         p->q2.flags=REG|DREFOBJ;
  288.         p->q2.reg=reg;
  289.         fprintf(f,",%s\n",regnames[p->q2.reg]);
  290.         if(equal) p->z=p->q2;
  291.     }
  292.     if((p->z.flags&DREFOBJ)&&(!(p->z.flags®)||p->z.reg<1||p->z.reg>8)){
  293.         reg=get_reg(f,0,p);
  294.         p->z.flags&=~DREFOBJ;
  295.         fprintf(f,"\tmove.l\t");probj2(f,&p->z,POINTER);
  296.         p->z.flags=REG|DREFOBJ;
  297.         p->z.reg=reg;
  298.         fprintf(f,",%s\n",regnames[p->z.reg]);
  299.     }
  300.     if(g_flags_val[0].l!=68040){
  301.     /*  Don't do it on 040 because it's slower. */
  302.         if(x_t[t&NQ]=='l'&&(t&NQ)!=FLOAT&&(c!=ASSIGN||!isreg(z))&&
  303.            c!=MULT&&c!=DIV&&c!=MOD&&c!=LSHIFT&&c!=RSHIFT&&c!=SETRETURN&&c!=PUSH&&c!=ADDI2P&&c!=SUBIFP&&
  304.            (!(p->z.flags®)||p->z.reg<9||p->z.reg>16)){
  305.             /*  Constants into registers.    */
  306.             if((p->q1.flags&KONST)&&isquickkonst(&p->q1.val,t)&&((c!=ADD&&c!=SUB&&c!=ADDI2P&&c!=SUBIFP)||!isquickkonst2(&p->q1.val,t))){
  307.                 eval_const(&p->q1.val,t);
  308.                 if((!zdeqto(d2zd(0.0),vdouble)||!zleqto(l2zl(0L),vlong)||!zuleqto(ul2zul(0UL),vulong))&®available(1)){
  309.                     reg=get_reg(f,1,p);
  310.                     move(f,&p->q1,0,0,reg,t);
  311.                     p->q1.flags=REG;p->q1.reg=reg;
  312.                     p->q1.val.vlong=l2zl(0L);
  313.                 }
  314.             }
  315.             if((p->q2.flags&KONST)&&isquickkonst(&p->q2.val,t)&&((c!=ADD&&c!=SUB&&c!=ADDI2P&&c!=SUBIFP)||!isquickkonst2(&p->q2.val,t))){
  316.                 eval_const(&p->q2.val,t);
  317.                 if((!zdeqto(d2zd(0.0),vdouble)||!zleqto(l2zl(0L),vlong)||!zuleqto(ul2zul(0UL),vulong))&®available(1)){
  318.                     reg=get_reg(f,1,p);
  319.                     move(f,&p->q2,0,0,reg,t);
  320.                     p->q2.flags=REG;p->q2.reg=reg;
  321.                     p->q2.val.vlong=l2zl(0L);
  322.                 }
  323.             }
  324.         }
  325.     }
  326.     return(p);
  327. }
  328. static void pr(FILE *f,struct IC *p)
  329. /*  Release registers and pop them from stack if necessary. */
  330. {
  331.     int i,size=0;
  332.     /*  To keep track of condition codes.   */
  333.     if((pushedreg&12)&&(p->code==TEST||p->code==COMPARE)){
  334.         char *fp;struct IC *branch;
  335.         if(g_flags_val[1].l>=68000&&((p->typf&NQ)==FLOAT||(p->typf&NQ)==DOUBLE)) fp="f"; else fp="";
  336.         branch=p;
  337.         while(branch->code<BEQ||branch->code>=BRA) branch=branch->next;
  338.         if((p->typf&UNSIGNED)||(p->typf&NQ)==POINTER){
  339.             fprintf(f,"\ts%s\t-2(a7)\n",ubranch[branch->code-BEQ]);
  340.         }else{
  341.             fprintf(f,"\t%ss%s\t-2(a7)\n",fp,ename[branch->code]+1);
  342.         }
  343.         stored_cc=1;
  344.     }
  345.     for(i=MAXR;i>0;i--){
  346.         if(regs[i]==2) regs[i]=0;
  347.         if(regs[i]&8){
  348.             regs[i]&=~8;
  349.             fprintf(f,"\tmove.l\tl%d,%s\n",pushlabel,regnames[i]);
  350.             if(i>=9) cc_set=0;
  351.         }
  352.         if(regs[i]&4){
  353.             regs[i]&=~4;
  354.             if(i<17) {fprintf(f,"\tmove.l\t(a7)+,%s\n",regnames[i]);stackoffset+=4;size+=4;}
  355.              else {fprintf(f,"\tfmove.x\t(a7)+,%s\n",regnames[i]);stackoffset+=12;size+=12;}
  356.             if(i>=9) cc_set=0;
  357.         }
  358.     }
  359.     if((pushedreg&12)&&(p->code==TEST||p->code==COMPARE))
  360.         fprintf(f,"\ttst.b\t-%d(a7)\n",size+2);
  361. }
  362. static void probj2(FILE *f,struct obj *p,int t)
  363. /*  Write object.   */
  364. {
  365.     if(p->am){
  366.     /*  Addressing modes.   */
  367.         if(g_flags[9]&USEDFLAG) {ierror(0);p->am=0;return;}
  368.         if(p->am->skal>=0){
  369.             long l=0;
  370.             if(p->flags&D16OFF) l=zl2l(p->val.vlong);
  371.             fprintf(f,"(%ld,%s",p->am->dist+l,regnames[p->am->basereg]);
  372.             if(p->am->dreg){
  373.                 fprintf(f,",%s",regnames[p->am->dreg&127]);
  374.                 if(p->am->dreg&128) fprintf(f,".w"); else fprintf(f,".l");
  375.                 if(p->am->skal) fprintf(f,"*%d",p->am->skal);
  376.             }
  377.             fprintf(f,")");
  378.             return;
  379.         }
  380.         if((p->flags&D16OFF)&&!zleqto(l2zl(0L),p->val.vlong)) ierror(0);
  381.         if(p->am->skal==-1){
  382.             fprintf(f,"(%s)+",regnames[p->am->basereg]);
  383.             return;
  384.         }
  385.         if(p->am->skal==-2){    /*  Noch nicht implementiert    */
  386.             fprintf(f,"-(%s)",regnames[p->am->basereg]);
  387.             return;
  388.         }
  389.     }
  390.     if(p->flags&DREFOBJ){
  391.         fprintf(f,"(");
  392.         if((p->flags&D16OFF)&&!zleqto(l2zl(0L),p->val.vlong))
  393.             {printval(f,&p->val,LONG,0);fprintf(f,",");}
  394.     }
  395.     if(p->flags&VARADR) fprintf(f,"#");
  396.     if(p->flags&VAR) {
  397.         if(p->v->storage_class==AUTO||p->v->storage_class==REGISTER){
  398.             if(p->flags®){
  399.                 fprintf(f,"%s",regnames[p->reg]);
  400.             }else{
  401.                 long os;
  402.                 os=zl2l(p->val.vlong);
  403.                 if(!(g_flags[8]&USEDFLAG)){
  404.                     if(!zlleq(l2zl(0L),p->v->offset)) os=os+loff-zl2l(p->v->offset);
  405.                      else              os=os+zl2l(p->v->offset);
  406.                     fprintf(f,"(%ld+l%d,a7)",os-stackoffset,offlabel);
  407.                 }else{
  408.                     if(!zlleq(l2zl(0L),p->v->offset)) os=os-zl2l(p->v->offset)+4;
  409.                      else              os=os-(zl2l(p->v->offset)+zl2l(szof(p->v->vtyp)));
  410.                     fprintf(f,"(%ld,a5)",os);
  411.                 }
  412.             }
  413.         }else{
  414.             if(!zleqto(l2zl(0L),p->val.vlong)){printval(f,&p->val,LONG,0);fprintf(f,"+");}
  415.             if(p->v->storage_class==STATIC&&(p->v->vtyp->flags&NQ)!=FUNKT){
  416.                 fprintf(f,"l%ld",zl2l(p->v->offset));
  417.             }else{
  418.                 fprintf(f,"_%s",p->v->identifier);
  419.             }
  420.             if((g_flags[5]&USEDFLAG)&&!(p->flags&VARADR)&&(p->v->vtyp->flags&NQ)!=FUNKT
  421.                &&!(p->v->tattr&5)&&((g_flags[7]&USEDFLAG)||!is_const(p->v->vtyp)) )
  422.               fprintf(f,"(a4)");
  423.         }
  424.     }
  425.     if((p->flags®)&&!(p->flags&VAR)) fprintf(f,"%s",regnames[p->reg]);
  426.     if(p->flags&KONST){
  427.         /*  This requires IEEE floats/doubles on the host compiler. */
  428.         if((t&NQ)==FLOAT||(t&NQ)==DOUBLE){
  429.             unsigned char *ip=(unsigned char *)&p->val.vfloat;
  430.             char *s;
  431.             if(gas) s="0x"; else s="$";
  432.             fprintf(f,"#%s%02x%02x%02x%02x",s,ip[0],ip[1],ip[2],ip[3]);
  433.             if(t==DOUBLE){
  434.                 if(DEBUG&1) printf("doubleconst=%f\n",p->val.vdouble);
  435.                 fprintf(f,"%02x%02x%02x%02x",ip[4],ip[5],ip[6],ip[7]);
  436.             }
  437.         }else {fprintf(f,"#");printval(f,&p->val,t&NU,0);}
  438.     }
  439.     if(p->flags&DREFOBJ) fprintf(f,")");
  440. }
  441. static char tsh[]={'w','l'};
  442. static int proflabel;
  443. static void function_top(FILE *f,struct Var *v,long offset)
  444. /*  Writes function header. */
  445. {
  446.     geta4=0;
  447.     if(gas){
  448.     }else{
  449.         if(g_flags[NQ]&USEDFLAG) fprintf(f,"\tsymdebug\n");
  450.         if(g_flags_val[0].l!=68000) fprintf(f,"\tmachine\t%ld\n",g_flags_val[0].l);
  451.         if(g_flags_val[1].l>68000) fprintf(f,"\tfpu\t1\n");
  452.         if(g_flags[4]&USEDFLAG) fprintf(f,"\tnear\tcode\n");
  453.         if(g_flags[5]&USEDFLAG) fprintf(f,"\tnear\ta4,-2\n");
  454.         fprintf(f,"\topt\t0\n\topt\tNQLPSM");
  455.         if(g_flags_val[0].l!=68040) fprintf(f,"R");
  456.         if((g_flags[12]&USEDFLAG)||(optflags&2)) fprintf(f,"BT");
  457.         fprintf(f,"\n");
  458.     }
  459.     if(section!=CODE){fprintf(f,codename);section=CODE;}
  460.     if(g_flags[6]&USEDFLAG){
  461.         proflabel=++label;
  462.         if(gas){
  463.             fprintf(f,"l%d:\n\t.byte\t\"%s\",0\n",proflabel,v->identifier);
  464.         }else{
  465.             fprintf(f,"l%d\n\tdc.b\t\"%s\",0\n",proflabel,v->identifier);
  466.         }
  467.     }
  468.     if(v->storage_class==EXTERN){
  469.         if(gas){
  470.             fprintf(f,"\t.global\t_%s\n",v->identifier);
  471.         }else{
  472.             fprintf(f,"\tpublic\t_%s\n",v->identifier);
  473.         }
  474.     }
  475.     if(gas){
  476.         fprintf(f,"\t.align\t4\n_%s:\n",v->identifier);
  477.     }else{
  478.         fprintf(f,"\tcnop\t0,4\n_%s\n",v->identifier);
  479.     }
  480.     if(g_flags[6]&USEDFLAG){
  481.         if(gas){
  482.             fprintf(f,"\tpea\tl%d\n\t.global\t__startprof\n\tjbsr\t__startprof\n\taddq.w\t#4,a7\n",proflabel);
  483.         }else{
  484.             fprintf(f,"\tpea\tl%d\n\tpublic\t__startprof\n\tjsr\t__startprof\n\taddq.w\t#4,a7\n",proflabel);
  485.         }
  486.     }
  487.     offset=-((offset+4-1)/4)*4;
  488.     loff=-offset;offlabel=++label;
  489.     if(!(g_flags[8]&USEDFLAG)){
  490.         if(offset<0) fprintf(f,"\tsub%s.%s\t#%ld,a7\n",quick[offset>=-8],strshort[offset>=-32768],-offset);
  491.     }else{
  492.         if(offset>=-32768||g_flags_val[0].l>=68020){
  493.             fprintf(f,"\tlink.%c\ta5,#%ld\n",tsh[offset<-32768],offset);
  494.         }else{
  495.             fprintf(f,"\tlink.w\ta5,#-32768\n");offset+=32768;
  496.             fprintf(f,"\tsub.%c\t#%ld,a5\n",tsh[offset<-32768],offset);
  497.         }
  498.     }
  499.     if(g_flags_val[1].l>68000&&float_used){
  500.         if(gas){
  501.             fprintf(f,"\t.word\t0xf227,l%d\n",freglabel);
  502.         }else{
  503.             fprintf(f,"\tfmovem.x\tl%d,-(a7)\n",freglabel);
  504.         }
  505.     }
  506.     if(gas){
  507.         fprintf(f,"\tmovem.l\t#l%d,-(a7)\n",reglabel);
  508.     }else{
  509.         fprintf(f,"\tmovem.l\tl%d,-(a7)\n",reglabel);
  510.     }
  511.     if(v->tattr&8) fprintf(f,"\txref\t_DATA_BAS_\n\tlea\t_DATA_BAS_+32766,a4\n");
  512. }
  513. static void function_bottom(FILE *f,struct Var *v,long offset)
  514. /*  Writes function footer. */
  515. {
  516.     int i,size=0;unsigned int pushval,popval;
  517.     *reglist=0;
  518.     pushval=popval=0;
  519.     if(v->tattr&8) geta4=1;
  520.     for(i=1;i<=16;i++){
  521.         if((regused[i]&&!regscratch[i]&&!regsa[i])||(i==5&&geta4)){
  522.             if(*reglist) strcat(reglist,"/");
  523.             strcat(reglist,regnames[i]);
  524.             if(i<9){  pushval|=(256>>i);popval|=(128<<i);}
  525.               else {  pushval|=(0x8000>>(i-9));popval|=(1<<(i-9));}
  526.             size+=4;
  527.         }
  528.     }
  529.     if(gas){
  530.         if(popval) fprintf(f,"\t.equ\tl%d,%u\n\tmovem.l\t(a7)+,#%u\n",reglabel,pushval,popval);
  531.             else fprintf(f,"\t.equ\tl%d,0\n",reglabel);
  532.     }else{
  533.         if(*reglist) fprintf(f,"l%d\treg\t%s\n\tmovem.l\t(a7)+,l%d\n",reglabel,reglist,reglabel);
  534.             else fprintf(f,"l%d\treg\n",reglabel);
  535.     }
  536.     *reglist=0;pushval=0xe000;popval=0xd000;
  537.     for(i=17;i<=MAXR;i++){
  538.         if(regused[i]&&!regscratch[i]&&!regsa[i]){
  539.             if(*reglist) strcat(reglist,"/");
  540.             strcat(reglist,regnames[i]);
  541.             pushval|=(1<<(i-17));popval|=(0x80>>(i-17));
  542.             size+=12;
  543.         }
  544.     }
  545.     if(g_flags_val[1].l>68000&&float_used){
  546.         if(gas){
  547.             if(popval!=0xd000) fprintf(f,"\t.equ\tl%d,0x%x\n\t.word\t0xf21f,0x%x\n",freglabel,(int)pushval,(int)popval);
  548.                 else fprintf(f,"\t.equ\tl%d,0xe000\n",freglabel);
  549.         }else{
  550.             if(*reglist) fprintf(f,"l%d\tfreg\t%s\n\tfmovem.x\t(a7)+,l%d\n",freglabel,reglist,freglabel);
  551.                 else fprintf(f,"l%d\tfreg\n",freglabel);
  552.         }
  553.     }
  554.     if(!(g_flags[8]&USEDFLAG)){
  555.         if(loff) fprintf(f,"\tadd%s.%s\t#%ld,a7\n",quick[loff<=8],strshort[loff<32768],loff);
  556.         if(gas){
  557.             fprintf(f,"\t.equ\tl%d,%d\n",offlabel,size);
  558.         }else{
  559.             fprintf(f,"l%d\tEQU\t%d\n",offlabel,size);
  560.         }
  561.     }else fprintf(f,"\tunlk\ta5\n");
  562.     if(g_flags[6]&USEDFLAG){
  563.         if(gas){
  564.             fprintf(f,"\tpea\tl%d\n\t.global\t__endprof\n\tjbsr\t__endprof\n\taddq.w\t#4,a7\n",proflabel);
  565.         }else{
  566.             fprintf(f,"\tpea\tl%d\n\tpublic\t__endprof\n\tjsr\t__endprof\n\taddq.w\t#4,a7\n",proflabel);
  567.         }
  568.     }
  569.     fprintf(f,"\trts\n");
  570. }
  571. static void move(FILE *f,struct obj *q,int qreg,struct obj *z,int zreg,int t)
  572. /*  erzeugt eine move Anweisung...Da sollen mal Optimierungen rein  */
  573. {
  574.     if(!zreg&&(z->flags&(REG|DREFOBJ))==REG) zreg=z->reg;
  575.     if(!qreg&&(q->flags&(REG|DREFOBJ))==REG) qreg=q->reg;
  576.     if(zreg==qreg&&zreg) return;
  577.     if(q&&(q->flags&VARADR)&&zreg>=1&&zreg<=8){
  578.         fprintf(f,"\tlea\t");
  579.         q->flags&=~VARADR;probj2(f,q,t);q->flags|=VARADR;
  580.         fprintf(f,",%s\n",regnames[zreg]);
  581.         return;
  582.     }
  583.     if(zreg>=9&&zreg<=16&&q&&(q->flags&KONST)&&isquickkonst(&q->val,t)){
  584.         fprintf(f,"\tmoveq\t");
  585.     }else{
  586.         if(zreg>=17||qreg>=17){
  587.             if(qreg>=17&&zreg>=17) fprintf(f,"\tfmove.x\t");
  588.              else fprintf(f,"\tfmove.%c\t",x_t[t&NQ]);
  589.         }else{
  590.             fprintf(f,"\tmove.%c\t",x_s[msizetab[t&NQ]]);
  591.         }
  592.     }
  593.     if(qreg) fprintf(f,"%s",regnames[qreg]); else probj2(f,q,t);
  594.     fprintf(f,",");
  595.     if(zreg) fprintf(f,"%s",regnames[zreg]); else probj2(f,z,t);
  596.     fprintf(f,"\n");
  597. }
  598. static void add(FILE *f,struct obj *q,int qreg,struct obj *z,int zreg,int t)
  599. /*  erzeugt eine add Anweisung...Da sollen mal Optimierungen rein   */
  600. {
  601.     if(!qreg&&!q) ierror(0);
  602.     if(!zreg&&!z) ierror(0);
  603.     if(!zreg&&(z->flags&(REG|DREFOBJ))==REG) zreg=z->reg;
  604.     if(!qreg&&(q->flags&KONST)&&isquickkonst2(&q->val,t)){
  605.         fprintf(f,"\taddq.%c\t",x_t[t&NQ]);
  606.     }else{
  607.         /*  hier noch Abfrage, ob #c.w,ax   */
  608.         fprintf(f,"\tadd.%c\t",x_t[t&NQ]);
  609.     }
  610.     if(qreg) fprintf(f,"%s",regnames[qreg]); else probj2(f,q,t);
  611.     fprintf(f,",");
  612.     if(zreg) fprintf(f,"%s",regnames[zreg]); else probj2(f,z,t);
  613.     fprintf(f,"\n");
  614. }
  615. static void sub(FILE *f,struct obj *q,int qreg,struct obj *z,int zreg,int t)
  616. /*  erzeugt eine sub Anweisung...Da sollen mal Optimierungen rein   */
  617. {
  618.     if(!zreg&&(z->flags&(REG|DREFOBJ))==REG) zreg=z->reg;
  619.     if(q&&(q->flags&KONST)&&isquickkonst2(&q->val,t)){
  620.         fprintf(f,"\tsubq.%c\t",x_t[t&NQ]);
  621.     }else{
  622.         /*  hier noch Abfrage, ob #c.w,ax   */
  623.         fprintf(f,"\tsub.%c\t",x_t[t&NQ]);
  624.     }
  625.     if(qreg) fprintf(f,"%s",regnames[qreg]); else probj2(f,q,t);
  626.     fprintf(f,",");
  627.     if(zreg) fprintf(f,"%s",regnames[zreg]); else probj2(f,z,t);
  628.     fprintf(f,"\n");
  629. }
  630. static void mult(FILE *f,struct obj *q,int qreg,struct obj *z,int zreg, int t,int c,struct IC *p)
  631. /*  erzeugt eine mult Anweisung...Da sollen mal Optimierungen rein  */
  632. /*  erzeugt auch div/mod etc.                                       */
  633. {
  634.     int modreg;
  635.     if(!qreg&&(q->flags&(REG|DREFOBJ))==REG) qreg=q->reg;
  636.     if(!zreg&&(z->flags&(REG|DREFOBJ))==REG) zreg=z->reg;
  637.     if((c==MULT||c==DIV||c==MOD)&&g_flags_val[0].l<68020&&msizetab[t&NQ]==4){
  638.         if(c==MULT){
  639.         /*  ist das mit get_reg(.,.,0) ok? nochmal ueberdenken...   */
  640.         /*  ...die ganze Routine am besten...                       */
  641.         /*  ...es war nicht, deshalb ist es jetzt geaendert         */
  642.             int dx,dy,t1,t2;
  643.             if(zreg>=9&&zreg<=16){
  644.                 dx=zreg;
  645.             }else{
  646.                 dx=get_reg(f,1,p);
  647.                 move(f,z,0,0,dx,t);
  648.             }
  649.             if(qreg>=9&&qreg<=16&&qreg!=dx){
  650.                 dy=qreg;
  651.             }else{
  652.                 dy=get_reg(f,1,p);
  653.                 move(f,q,0,0,dy,t);
  654.             }
  655.             t1=get_reg(f,1,p);t2=get_reg(f,1,p);
  656.             if(t1==dx||t2==dx||t1==dy||t2==dy) ierror(0);
  657.             fprintf(f,"\tmove.l\t%s,%s\n",regnames[dx],regnames[t1]);
  658.             fprintf(f,"\tmove.l\t%s,%s\n",regnames[dy],regnames[t2]);
  659.             fprintf(f,"\tswap\t%s\n",regnames[t1]);
  660.             fprintf(f,"\tswap\t%s\n",regnames[t2]);
  661.             fprintf(f,"\tmulu.w\t%s,%s\n",regnames[dy],regnames[t1]);
  662.             fprintf(f,"\tmulu.w\t%s,%s\n",regnames[dx],regnames[t2]);
  663.             fprintf(f,"\tmulu.w\t%s,%s\n",regnames[dy],regnames[dx]);
  664.             fprintf(f,"\tadd.w\t%s,%s\n",regnames[t2],regnames[t1]);
  665.             fprintf(f,"\tswap\t%s\n",regnames[t1]);
  666.             fprintf(f,"\tclr.w\t%s\n",regnames[t1]);
  667.             fprintf(f,"\tadd.l\t%s,%s\n",regnames[t1],regnames[dx]);
  668.             if(zreg!=dx) move(f,0,t1,z,0,t);
  669.         }else ierror(0);
  670.         return;
  671.     }
  672.     if(c==MULT){
  673.         /*  das duerfte nur der Aesthetik dienen... */
  674.         if(t&UNSIGNED) fprintf(f,"\tmulu.%c\t",x_t[t&NQ]); else fprintf(f,"\tmuls.%c\t",x_t[t&NQ]);
  675.     }
  676.     if(c==DIV){
  677.         if(t&UNSIGNED) fprintf(f,"\tdivu.%c\t",x_t[t&NQ]); else fprintf(f,"\tdivs.%c\t",x_t[t&NQ]);
  678.     }
  679.     if(qreg) fprintf(f,"%s",regnames[qreg]); else probj2(f,q,t);
  680.     fprintf(f,",");
  681.     /*  eigentlich muss zreg!=0 sein...     */
  682.     if(zreg) fprintf(f,"%s",regnames[zreg]); else probj2(f,z,t);
  683.     fprintf(f,"\n");
  684. }
  685. static struct IC *am_freedreg[9],*am_shiftdreg[9];
  686. static struct IC *am_dist_ic[9],*am_dreg_ic[9],*am_use[9];
  687. /*  am_dist_ic und am_dreg_ic werden auch fuer (ax)+ benutzt    */
  688. static long am_dist[9],am_dreg[9],am_base[9],am_inc[9],am_skal[9],am_dbase[9];
  689. #define AMS sizeof(struct AddressingMode)
  690.  
  691. static int opsize(struct IC *p,int reg)
  692. /*  Liefert die Groesse in Bytes, mit der im IC auf (reg) zugegriffen wird. */
  693. {
  694.     int c=p->code;
  695.     if(c==ADDI2P||c==SUBIFP){
  696.         if((p->q2.flags®)&&p->q2.reg==reg)
  697.             return zl2l(sizetab[p->typf&NQ]);
  698.         return 4;
  699.     }
  700.     if(c>=CONVCHAR&&c<=CONVULONG){
  701.         if((p->z.flags®)&&p->z.reg==reg)
  702.             return zl2l(sizetab[p->typf&NQ]);
  703.         if(c==CONVCHAR||c==CONVUCHAR) return 1;
  704.         else if(c==CONVSHORT||c==CONVUSHORT) return 2;
  705.         else if(c==DOUBLE) return 8;
  706.         else return 4;
  707.     }
  708.     return zl2l(sizetab[p->typf&NQ]);
  709. }
  710. static void clear_am(int reg)
  711. /*  loescht Werte fuer erweiterte Adressierungsarten fuer Register reg  */
  712. {
  713.     if(reg<0||reg>16) ierror(0);
  714.     if(DEBUG&32) printf("clear_am(%s)\n",regnames[reg]);
  715.     if(reg<=8){
  716.         am_dist_ic[reg]=am_dreg_ic[reg]=am_use[reg]=0;
  717.         am_dist[reg]=am_dreg[reg]=am_base[reg]=am_inc[reg]=0;
  718.     }else{
  719.         reg-=8;
  720.         am_freedreg[reg]=am_shiftdreg[reg]=0;
  721.         am_skal[reg]=am_dbase[reg]=0;
  722.     }
  723. }
  724. static int addressing(void)
  725. /*  Untersucht ICs auf erweiterte Addresierungsarten    */
  726. {
  727.     struct IC *p;int count,localused=0;
  728.     if(DEBUG&32) printf("addressing() started\n");
  729.     for(count=1;count<=16;count++) clear_am(count);
  730.     for(count=0,p=first_ic;p;p=p->next){
  731.         int c=p->code,q1reg,q2reg,zreg;
  732.         if(p->q1.flags®) q1reg=p->q1.reg; else q1reg=0;
  733.         if(p->q2.flags®) q2reg=p->q2.reg; else q2reg=0;
  734.         if(p->z.flags®) zreg=p->z.reg; else zreg=0;
  735.         if(c==ADDI2P) c=ADD;
  736.         if(c==SUBIFP) c=SUB;
  737.         if(DEBUG&32) pric2(stdout,p);
  738.         if(!localused){
  739.             if((p->q1.flags&(VAR|REG))==VAR&&(p->q1.v->storage_class==AUTO||p->q1.v->storage_class==REGISTER)&&p->q1.v->offset>=0)
  740.                 localused=1;
  741.             if((p->q2.flags&(VAR|REG))==VAR&&(p->q2.v->storage_class==AUTO||p->q2.v->storage_class==REGISTER)&&p->q2.v->offset>=0)
  742.                 localused=1;
  743.             if((p->z.flags&(VAR|REG))==VAR&&(p->z.v->storage_class==AUTO||p->z.v->storage_class==REGISTER)&&p->z.v->offset>=0)
  744.                 localused=1;
  745.             if(DEBUG&32&&localused==1) printf("localused=1\n");
  746.         }
  747.         if(c==ASSIGN&&isreg(q1)&&isreg(z)&&q1reg>=1&&q1reg<=8&&zreg>=1&&zreg<=8){
  748.         /*  fuer (ax)+  */
  749.             int i;
  750.             clear_am(q1reg);
  751.             for(i=1;i<=8;i++)
  752.                 if(am_base[i]==zreg||am_base[i]==q1reg) clear_am(i);
  753.             clear_am(zreg);am_base[zreg]=q1reg;am_dreg_ic[zreg]=p;
  754.             if(DEBUG&32) printf("move %s,%s found\n",regnames[q1reg],regnames[zreg]);
  755.             continue;
  756.         }
  757.         if(c==MULT&&g_flags_val[0].l>=68020&&(p->q2.flags&KONST)&&isreg(z)&&zreg>=9&&zreg<=16){
  758.         /*  dx=a*const, fuer Skalierung    */
  759.             int dreg=zreg-8;
  760.             if(dreg<1||dreg>8) ierror(0);
  761.             if(q1reg>=1&&q1reg<=16){
  762.                 if(isreg(q1)&&(q1reg>8||am_use[q1reg]!=p)) clear_am(q1reg);
  763.                 if((p->q1.flags&DREFOBJ)&&q1reg<=8&&am_use[q1reg]) clear_am(q1reg);
  764.             }
  765.             if(DEBUG&32) printf("mult x,const->dreg found\n");
  766.             if(am_skal[dreg]) {clear_am(zreg);continue;}
  767.             eval_const(&p->q2.val,p->typf);
  768.             am_skal[dreg]=zl2l(vlong);
  769.             if(am_skal[dreg]!=2&&am_skal[dreg]!=4&&am_skal[dreg]!=8)
  770.                 {clear_am(zreg);continue;}
  771.             am_shiftdreg[dreg]=p;
  772.             if(isreg(q1)&&q1reg>=9&&q1reg<=16) am_dbase[dreg]=q1reg; else am_dbase[dreg]=zreg;
  773.             if(DEBUG&32) printf("is usable\n");
  774.             continue;
  775.         }
  776.         if((c==ADD||c==SUB)&&(p->q2.flags&KONST)&&zreg>=1&&zreg<=8&&isreg(z)){
  777.         /*  add ax,#const,ax->az Test auf d8/16 fehlt noch (nicht mehr) */
  778.             long l;
  779.             if(zreg<1||zreg>8) ierror(0);
  780.             eval_const(&p->q2.val,p->typf);
  781.             l=zl2l(vlong);
  782.             if(c==SUB) l=-l;
  783.             if(q1reg==zreg&&am_use[zreg]&&(l==1||l==2||l==4)){
  784.                 if(l==opsize(am_use[zreg],zreg)){
  785.                     struct IC *op=am_use[zreg];
  786.                     struct obj *o=0;
  787.                     if(DEBUG&32){ printf("found postincrement:\n");pric2(stdout,op);pric2(stdout,p);}
  788.                     if((op->q1.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&op->q1.reg==zreg){
  789.                         if(DEBUG&32) printf("q1\n");
  790.                         o=&op->q1;
  791.                     }
  792.                     if((op->q2.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&op->q2.reg==zreg){
  793.                         if(DEBUG&32) printf("q2\n");
  794.                         if(o) continue; else o=&op->q2;
  795.                     }
  796.                     if((op->z.flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&op->z.reg==zreg){
  797.                         if(DEBUG&32) printf("z\n");
  798.                         if(o) continue; else o=&op->z;
  799.                     }
  800.                     o->am=mymalloc(AMS);
  801.                     o->am->basereg=zreg;
  802.                     o->am->skal=-1;
  803.                     o->am->dist=0;
  804.                     o->am->dreg=0;
  805.                     p=p->prev;
  806.                     remove_IC(p->next);
  807.                     clear_am(zreg);continue;
  808.                 }
  809.             }
  810.             clear_am(q1reg);
  811.             if(am_dist[zreg]||am_inc[zreg]||am_use[zreg]) {clear_am(zreg);continue;} /* nur ein Offset */
  812.             if(isreg(q1)&&q1reg==zreg&&(l==1||l==2||l==4)){
  813.             /*  ax+=const, fuer (ax)+   */
  814.                 int i,f;
  815.                 for(f=0,i=1;i<=8;i++){
  816.                     if(am_base[i]==zreg&&!am_dreg[i]&&!am_dist[i]){
  817.                         if(f) ierror(0);
  818.                         am_inc[i]=l;am_dist_ic[i]=p;f=i;
  819.                         if(DEBUG&32) printf("inc %s found\n",regnames[i]);
  820.                     }
  821.                 }
  822.                 if(f) continue;
  823.             }
  824.             am_dist[zreg]=l;
  825.             if(DEBUG&32) printf("dist=%ld\n",am_dist[zreg]);
  826.             if(g_flags_val[0].l<68020){
  827.             /*  bei <68020 darf der Offset nur 16bit oder 8bit bei dreg sein */
  828.                 if((am_dreg[zreg]&&(am_dist[zreg]<-128||am_dist[zreg]>127))||am_dist[zreg]<-32768||am_dist[zreg]>32767)
  829.                     {clear_am(zreg);continue;}
  830.             }
  831.             am_dist_ic[zreg]=p;
  832.             if(am_base[zreg]){
  833.                 if(q1reg!=zreg||!isreg(q1)) {clear_am(zreg);continue;}
  834.             }else{
  835.                 if(q1reg>=1&&q1reg<=8&&isreg(q1)) am_base[zreg]=q1reg; else am_base[zreg]=zreg;
  836.                 if(DEBUG&32) printf("%s potential base for %s\n",regnames[am_base[zreg]],regnames[zreg]);
  837.             }
  838.             if(DEBUG&32) printf("add #const,%s found\n",regnames[zreg]);
  839.             continue;
  840.         }
  841.         if(c==ADD&&q2reg>=9&&q2reg<=16&&isreg(q2)&&zreg>=1&&zreg<=8&&isreg(z)&&(p->q1.flags&(REG|DREFOBJ))!=(REG|DREFOBJ)){
  842.         /*  add ax,dy->az   */
  843.             int i;
  844.             if(zreg<1||zreg>8) ierror(0);
  845.             for(i=1;i<=8;i++)
  846.                 if(am_dreg[i]==q2reg){ clear_am(q2reg);clear_am(i);}
  847.             clear_am(q1reg);
  848.             if(am_dreg[zreg]||am_inc[zreg]||am_use[zreg]) {clear_am(zreg);continue;} /* nur ein Regoffset */
  849.             if(g_flags_val[0].l<68020&&(am_dist[zreg]<-128||am_dist[zreg]>127))
  850.                 {clear_am(zreg);continue;} /* bei <68020 nur 8bit Offset */
  851.             am_dreg[zreg]=q2reg;
  852.             if((p->typf&NQ)==SHORT) am_dreg[zreg]|=128; /* dx.w statt dx.l */
  853.             am_dreg_ic[zreg]=p;
  854.             if(am_base[zreg]){
  855.                 if(q1reg!=zreg||!isreg(q1)) {clear_am(zreg);continue;}
  856.             }else{
  857.                 if(q1reg>=1&&q1reg<=8&&isreg(q1)) am_base[zreg]=q1reg; else am_base[zreg]=zreg;
  858.             }
  859.             if(DEBUG&32) printf("add %s,%s found\n",regnames[q2reg],regnames[zreg]);
  860.             continue;
  861.         }
  862.         if(c==FREEREG){
  863.         /*  wir koennen den Modus tatsaechlich benutzen */
  864.             struct AddressingMode *am;struct IC *p1,*p2;int dreg,i;
  865.             if(DEBUG&32) printf("freereg %s found\n",regnames[p->q1.reg]);
  866.             if(q1reg>=9&&q1reg<=16) {am_freedreg[q1reg-8]=p;if(DEBUG&32) printf("freedreg[%d]=%lx\n",q1reg-8,(long)p);}
  867.             if(q1reg>8) continue;
  868.             if(DEBUG&32) printf("use=%p,base=%p,dist=%p,dreg=%p\n",(void*)am_use[q1reg],(void*)am_base[q1reg],(void*)am_dist[q1reg],(void*)am_dreg[q1reg]);
  869.             for(i=1;i<=8;i++) if(am_base[i]==q1reg) clear_am(i);
  870.             if(!am_use[q1reg]||!am_base[q1reg]) continue;
  871.             if(am_inc[q1reg]&&am_inc[q1reg]!=opsize(am_use[q1reg],q1reg))
  872.                 {clear_am(q1reg);continue;}
  873.             if(!am_dist[q1reg]&&!am_dreg[q1reg]&&!am_inc[q1reg]) continue;
  874.             p1=am_dist_ic[q1reg];p2=am_dreg_ic[q1reg];
  875.             if(DEBUG&32){
  876.                 printf("could really use %s\n",regnames[q1reg]);
  877.                 if(p1) pric2(stdout,p1);
  878.                 if(p2) pric2(stdout,p2);
  879.             }
  880.             if(am_base[q1reg]==q1reg){
  881.                 if(p1) {p1->q2.flags=0;p1->code=ASSIGN;p1->q2.val.vlong=l2zl(4L);p1->typf=POINTER;}
  882.                 if(p2) {p2->q2.flags=0;p2->code=ASSIGN;p2->q2.val.vlong=l2zl(4L);p2->typf=POINTER;}
  883.             }else{
  884.                 if(p1) remove_IC(p1);
  885.                 if(p2) remove_IC(p2);
  886.             }
  887.             dreg=(am_dreg[q1reg]&127)-8;
  888.             am=mymalloc(AMS);
  889.             am->skal=0;
  890.             am->basereg=am_base[q1reg];
  891.             am->dist=am_dist[q1reg];
  892.             am->dreg=am_dreg[q1reg];
  893.             if(am_inc[q1reg]) am->skal=-1;
  894.             if(dreg>0){
  895.                 /*  bei (d,ax,dy) das freereg dy nach hinten verschieben    */
  896.                 if(dreg<1||dreg>8) ierror(0);
  897.                 if(p1=am_freedreg[dreg]){
  898.                     if(DEBUG&32){
  899.                         printf("freereg %s moved from %p to %p\n",regnames[dreg+8],(void*)p1,(void*)p);
  900.                         pric2(stdout,p1);
  901.                     }
  902.                     if(p1->code!=FREEREG){ierror(0);printf("freereg[%d]=%p\n",dreg,(void*)p1);continue;}
  903.                     if(!p1->next) {ierror(0);continue;}
  904.                     if(!p1->prev) {ierror(0);continue;}
  905.                     p1->prev->next=p1->next;
  906.                     p1->next->prev=p1->prev;
  907.                     p1->next=p->next;
  908.                     p1->prev=p;
  909.                     if(p->next) p->next->prev=p1;
  910.                     p->next=p1;
  911.                 }
  912.                 if(am_skal[dreg]){
  913.                 /*  Skalierung bearbeiten   */
  914.                     if(p1){
  915.                         am->skal=am_skal[dreg];
  916.                         am->dreg=am_dbase[dreg];
  917.                         p1=am_shiftdreg[dreg];
  918.                         if(DEBUG&32) pric2(stdout,p1);
  919.                         if(am_dbase[dreg]==dreg+8){
  920.                             p1->code=ASSIGN;p1->q2.flags=0;p1->q2.val.vlong=sizetab[p1->typf&NQ];
  921.                         }else remove_IC(p1);
  922.                     }
  923.                     clear_am(dreg+8);
  924.                 }
  925.             }
  926.             /*  das hier duerfte unnoetig sein, da die Adressierungsart in  */
  927.             /*  einem IC eigentlich hoechstens einmal vorkommen darf        */
  928.             if(q1reg<0||q1reg>8) ierror(0);
  929.             p1=am_use[q1reg];
  930.             if(DEBUG&32) pric2(stdout,p1);
  931.             if(p1->code==PUSH&&p1->q1.reg==q1reg&&((p1->q1.flags&(DREFOBJ|REG))==(REG))){
  932.                 p1->q1.am=mymalloc(AMS);
  933.                 memcpy(p1->q1.am,am,AMS);
  934.                 p->q1.val.vlong=l2zl(0L);
  935.                 p1->code=PEA;
  936.                 if(DEBUG&32) printf("q1 patched\n");
  937.             }
  938.             if(p1->q1.reg==q1reg&&((p1->q1.flags&(DREFOBJ|REG))==(DREFOBJ|REG))){
  939.                 p1->q1.am=mymalloc(AMS);
  940.                 memcpy(p1->q1.am,am,AMS);
  941.                 p1->q1.val.vlong=l2zl(0L);
  942.                 if(DEBUG&32) printf("q1 patched\n");
  943.             }
  944.             if(p1->q2.reg==q1reg&&((p1->q2.flags&(DREFOBJ|REG))==(DREFOBJ|REG))){
  945.                 p1->q2.am=mymalloc(AMS);
  946.                 memcpy(p1->q2.am,am,AMS);
  947.                 p1->q2.val.vlong=l2zl(0L);
  948.                 if(DEBUG&32) printf("q2 patched\n");
  949.             }
  950.             if(p1->z.reg==q1reg&&((p1->z.flags&(DREFOBJ|REG))==(DREFOBJ|REG))){
  951.                 p1->z.am=mymalloc(AMS);
  952.                 memcpy(p1->z.am,am,AMS);
  953.                 p1->z.val.vlong=l2zl(0L);
  954.                 if(DEBUG&32) printf("z patched\n");
  955.             }
  956.             free(am);count++;
  957.             clear_am(q1reg);
  958.             continue;
  959.         }
  960.         if(c>=LABEL&&c<=BRA){
  961.             int i;      /*  ueber basic blocks hinweg unsicher  */
  962.             for(i=1;i<=16;i++) clear_am(i);
  963.             continue;
  964.         }
  965.         /*  Wenn Libraryaufrufe noetig sind (floating point ohne FPU oder   */
  966.         /*  32bit mul/div/mod ohne 020+) keine Addressierungsarten nutzen   */
  967.         if(g_flags_val[1].l<68000&&(p->typf==FLOAT||p->typf==DOUBLE||c==CONVFLOAT||c==CONVDOUBLE)){
  968.             int i;
  969.             for(i=1;i<=16;i++) clear_am(i);
  970.             continue;
  971.         }
  972.         if(g_flags_val[0].l<68020&&(c==DIV||c==MOD)){
  973.             int i;
  974.             for(i=1;i<=16;i++) clear_am(i);
  975.             continue;
  976.         }
  977.         if(c==PUSH&&((p->q1.flags&(DREFOBJ|REG))==REG&&q1reg<=8&&!am_use[q1reg]&&(am_inc[q1reg]||am_dist[q1reg]||am_dreg[q1reg]))){
  978.             if(q1reg<1||q1reg>8) ierror(0);
  979.             if(am_inc[q1reg]&&am_inc[q1reg]!=msizetab[p->typf&NQ]) clear_am(q1reg); else am_use[q1reg]=p;
  980.             if(DEBUG&32) printf("use of %s found\n",regnames[q1reg]);
  981.             continue;
  982.         }
  983.         if(((p->q1.flags&(DREFOBJ|REG))==(DREFOBJ|REG)&&q1reg<=8)){
  984.             if(q1reg<1||q1reg>8) ierror(0);
  985.             if(am_use[q1reg]&&(am_use[q1reg]!=p||am_inc[q1reg])) clear_am(q1reg); else am_use[q1reg]=p;
  986.             if(am_inc[q1reg]&&am_inc[q1reg]!=sizetab[p->typf&NQ]) clear_am(q1reg);
  987.             if(DEBUG&32) printf("use of %s found\n",regnames[q1reg]);
  988.         }
  989.         if(((p->q2.flags&(DREFOBJ|REG))==(DREFOBJ|REG)&&q2reg<=8)){
  990.             if(q2reg<1||q2reg>8) ierror(0);
  991.             if(am_use[q2reg]&&(am_use[q2reg]!=p||am_inc[q2reg])) clear_am(q2reg); else am_use[q2reg]=p;
  992.             if(am_inc[q2reg]&&am_inc[q2reg]!=sizetab[p->typf&NQ]) clear_am(q2reg);
  993.             if(DEBUG&32) printf("use of %s found\n",regnames[q2reg]);
  994.         }
  995.         if(((p->z.flags&(DREFOBJ|REG))==(DREFOBJ|REG)&&zreg<=8)){
  996.             if(zreg<1||zreg>8) ierror(0);
  997.             if(am_use[zreg]&&(am_use[zreg]!=p||am_inc[zreg])) clear_am(zreg); else am_use[zreg]=p;
  998.             if(am_inc[zreg]&&am_inc[zreg]!=sizetab[p->typf&NQ]) clear_am(zreg);
  999.             if(DEBUG&32) printf("use of %s found\n",regnames[zreg]);
  1000.         }
  1001.         if(c==ALLOCREG){
  1002.         /*  allocreg zaehlt als zerstoerung von reg */
  1003.             p->z.flags=REG;
  1004.             p->z.reg=zreg=q1reg;
  1005.         }
  1006.         if(q1reg>=1&&q1reg<=16&&isreg(q1)&&(q1reg>8||am_use[q1reg]!=p)) clear_am(q1reg);
  1007.         if(q2reg>=1&&q2reg<=16&&isreg(q2)&&(q2reg>8||am_use[q2reg]!=p)) clear_am(q2reg);
  1008.         if(zreg>=1&&zreg<=16&&isreg(z)) clear_am(zreg);
  1009.         if(isreg(z)&&zreg<=16){
  1010.         /*  schauen, ob eines der Register ueberschrieben wird  */
  1011.         /*  wohl noch sehr langsam                              */
  1012.             int i;
  1013.             for(i=1;i<=8;i++)
  1014.                 if(!am_use[i]&&(am_base[i]==zreg||(am_dreg[i]&127)==zreg)) clear_am(i);
  1015.         }
  1016.         if(c==ALLOCREG) p->z.flags=0;
  1017.     }
  1018.     if(DEBUG&1) printf("%d addressingmodes used, localused=%d\n",count,localused);
  1019.     return(localused);
  1020. }
  1021. static int alignment(struct obj *o)
  1022. /*  versucht rauszufinden, wie ein Objekt alignet ist   */
  1023. {
  1024.     /*  wenn es keine Variable ist, kann man nichts aussagen    */
  1025.     long os;
  1026.     if((o->flags&(DREFOBJ|VAR))!=VAR||o->am) return(0);
  1027.     if(!o->v) ierror(0);
  1028.     os=zl2l(o->val.vlong);
  1029.     if(o->v->storage_class==AUTO||o->v->storage_class==REGISTER){
  1030.         if(!(g_flags[8]&USEDFLAG)){
  1031.             if(!zlleq(l2zl(0L),o->v->offset)) os=os+loff-zl2l(o->v->offset);
  1032.              else              os=os+zl2l(o->v->offset);
  1033.         }else{
  1034.             if(!zlleq(l2zl(0L),o->v->offset)) os=os-zl2l(o->v->offset);
  1035.              else              os=os-(zl2l(o->v->offset)+zl2l(szof(o->v->vtyp)));
  1036.         }
  1037.     }
  1038.     return(os&3);
  1039. }
  1040. static void assign(FILE *f,struct IC *p,struct obj *q,struct obj *z,int c,long size,int t)
  1041. /*  Generiert Code fuer Zuweisungen und PUSH.   */
  1042. {
  1043.     /*  auch noch sehr fpu-spezifisch   */
  1044.     if((t&NQ)==FLOAT||(t&NQ)==DOUBLE){
  1045.         if(q&&(q->flags&KONST)){
  1046.             if(z&&(z->flags&(DREFOBJ|REG))==REG){
  1047.             /*  FP-Konstante->Register (muss immer reinpassen)  */
  1048.                 if(z->reg>=17) fprintf(f,"\tfmove"); else fprintf(f,"\tmove");
  1049.                 fprintf(f,".%c\t",x_t[t&NQ]);probj2(f,q,t);
  1050.                 fprintf(f,",%s\n",regnames[z->reg]);
  1051.             }else{
  1052.             /*  FP-Konstante->Speicher (evtl. auf zweimal)  */
  1053.                 int m;unsigned char *ip=(unsigned char *)&q->val.vfloat; /* nicht sehr schoen  */
  1054.                 char *s;
  1055.                 if(gas) s="0x"; else s="$";
  1056.                 if(c==PUSH&&t==DOUBLE){
  1057.                     fprintf(f,"\tmove.l\t#%s%02x%02x%02x%02x,-(a7)\n",s,ip[4],ip[5],ip[6],ip[7]);
  1058.                     stackoffset-=4;
  1059.                 }
  1060.                 fprintf(f,"\tmove.l\t#%s%02x%02x%02x%02x,",s,ip[0],ip[1],ip[2],ip[3]);
  1061.                 if(c==ASSIGN) probj2(f,z,t); else {fprintf(f,"-(a7)");stackoffset-=4;}
  1062.                 fprintf(f,"\n");
  1063.                 if(t!=DOUBLE||c==PUSH) return;
  1064.                 m=0;
  1065.                 if(z&&z->flags®){
  1066.                     m=1;z->flags|=D16OFF;
  1067.                     z->val.vlong=l2zl(0L);
  1068.                 }
  1069.                 vlong=l2zl(4L);
  1070.                 z->val.vlong=zladd(z->val.vlong,vlong);
  1071.                 fprintf(f,"\tmove.l\t#%s%02x%02x%02x%02x,",s,ip[4],ip[5],ip[6],ip[7]);
  1072.                 probj2(f,z,t);
  1073.                 fprintf(f,"\n");
  1074.                 if(m){
  1075.                     z->flags&=~D16OFF;vlong=l2zl(4L);
  1076.                     z->val.vlong=zlsub(z->val.vlong,vlong);
  1077.                 }
  1078.             }
  1079.             return;
  1080.         }
  1081.         if((q&&(q->flags®)&&q->reg>=17)||(z&&(z->flags®)&&z->reg>=17)){
  1082.             if(c==ASSIGN&&q->reg==z->reg) return;
  1083.             if(c==ASSIGN){ move(f,q,0,z,0,t);return;}
  1084.             fprintf(f,"\tfmove.%c\t",x_t[t&NQ]);
  1085.             probj2(f,q,t);
  1086.             fprintf(f,",");
  1087.             if(c==PUSH) {fprintf(f,"-(a7)");stackoffset-=size;} else probj2(f,z,t);
  1088.             fprintf(f,"\n");return;
  1089.         }
  1090.     }
  1091.     if(size<=4&&(t&NQ)!=ARRAY&&((t&NQ)!=CHAR||size==1)){
  1092.         if((t&NQ)==STRUCT||(t&NQ)==UNION){
  1093.             if(size==2) t=SHORT; else t=LONG;
  1094.         }
  1095.         if(c==ASSIGN){move(f,q,0,z,0,t);return;}
  1096.         /*  Sonderfall pea  */
  1097.         if((q->flags&VARADR)&&c==PUSH){
  1098.             fprintf(f,"\tpea\t");
  1099.             q->flags&=~VARADR; probj2(f,q,t); q->flags|=VARADR;
  1100.             fprintf(f,"\n"); stackoffset-=4;return;
  1101.         }
  1102.         fprintf(f,"\tmove.%c\t",x_s[size]);
  1103.         probj2(f,q,t);
  1104.         fprintf(f,",");
  1105.         if(c==PUSH) {fprintf(f,"-(a7)");stackoffset-=size;} else probj2(f,z,t);
  1106.         fprintf(f,"\n");return;
  1107.     }else{
  1108.         int a1,a2,qreg,zreg,dreg,s=size,loops,scratch=0;char *cpstr;
  1109.         struct IC *m;
  1110.         for(m=p->next;m&&m->code==FREEREG;m=m->next){
  1111.             if(q&&m->q1.reg==q->reg) scratch|=1;
  1112.             if(z&&m->q1.reg==z->reg) scratch|=2;
  1113.         }
  1114.         if(c==PUSH) cpstr="\tmove.%c\t-(%s),-(%s)\n"; else cpstr="\tmove.%c\t(%s)+,(%s)+\n";
  1115.         if((c==PUSH||(scratch&1))&&(q->flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&q->reg>=1&&q->reg<=8&&!q->am){
  1116.             qreg=q->reg;
  1117.             if(c==PUSH)
  1118.                 fprintf(f,"\tadd%s.%s\t#%ld,%s\n",quick[s<=8],strshort[s<=32767],(long)s,regnames[q->reg]);
  1119.         }else{
  1120.             if(c!=ASSIGN&&!regavailable(0)) qreg=pget_reg(f,0,p);
  1121.                 else qreg=get_reg(f,0,p);
  1122.             if(c==PUSH){q->flags|=D16OFF; q->val.vlong=zladd(q->val.vlong,l2zl((long)s));}
  1123.             fprintf(f,"\tlea\t");probj2(f,q,POINTER);
  1124.             if(c==PUSH) q->val.vlong=zlsub(q->val.vlong,l2zl((long)s));
  1125.             fprintf(f,",%s\n",regnames[qreg]);
  1126.         }
  1127.         if(c==PUSH){
  1128.             zreg=8;
  1129. /*            fprintf(f,"\tadd%s.%s\t#%ld,%s\n",quick[s<=8],strshort[s<=32767],(long)s,regnames[qreg]);*/
  1130.         }else{
  1131.             if((scratch&2)&&(z->flags&(REG|DREFOBJ))==(REG|DREFOBJ)&&z->reg>=1&&z->reg<=8&&!z->am){
  1132.                 zreg=z->reg;
  1133.             }else{
  1134.                 zreg=get_reg(f,0,p);
  1135.                 fprintf(f,"\tlea\t");probj2(f,z,POINTER);
  1136.                 fprintf(f,",%s\n",regnames[zreg]);
  1137.             }
  1138.         }
  1139.         a1=alignment(q);
  1140.         if(c!=PUSH)  a2=alignment(z); else a2=0;
  1141.         /*  wenn Typ==CHAR, dann ist das ein inline_memcpy und wir nehmen   */
  1142.         /*  das unguenstigste Alignment an                                  */
  1143.         if((t&NQ)==CHAR){ a1=1;a2=2;}
  1144.  
  1145.         if((a1&1)&&(a2&1)){fprintf(f,cpstr,'b',regnames[qreg],regnames[zreg]);s--;a1&=~1;a2&=~1;}
  1146.         if((a1&2)&&(a2&2)){fprintf(f,cpstr,'w',regnames[qreg],regnames[zreg]);s-=2;a1&=~2;a2&=~2;}
  1147.         if(!(a1&1)&&!(a2&1)) loops=s/16-1; else loops=s/4-1;
  1148.         if(loops>0){
  1149.             if(c!=ASSIGN&&!regavailable(1)) dreg=pget_reg(f,0,p);
  1150.                 else dreg=get_reg(f,1,p);
  1151.             fprintf(f,"\tmove%s.l\t#%d,%s\nl%d:\n",quick[loops>=-128&&loops<=127],loops,regnames[dreg],++label);
  1152.         }
  1153.         if(loops>=0){
  1154.             int t;
  1155.             if(!(a1&1)&&!(a2&1)) t='l'; else t='b';
  1156.             fprintf(f,cpstr,t,regnames[qreg],regnames[zreg]);
  1157.             fprintf(f,cpstr,t,regnames[qreg],regnames[zreg]);
  1158.             fprintf(f,cpstr,t,regnames[qreg],regnames[zreg]);
  1159.             fprintf(f,cpstr,t,regnames[qreg],regnames[zreg]);
  1160.         }
  1161.         if(loops>0){
  1162.             if(loops<=32767&&loops>=-32768){
  1163.                 fprintf(f,"\tdbra\t%s,l%d\n",regnames[dreg],label);
  1164.             }else{
  1165.                 fprintf(f,"\tsubq.l\t#1,%s\n\tbge\tl%d\n",regnames[dreg],label);
  1166.             }
  1167.         }
  1168.         if(!(a1&1)&&!(a2&1)){
  1169.             if(s&8){
  1170.                 fprintf(f,cpstr,'l',regnames[qreg],regnames[zreg]);
  1171.                 fprintf(f,cpstr,'l',regnames[qreg],regnames[zreg]);
  1172.             }
  1173.             if(s&4) fprintf(f,cpstr,'l',regnames[qreg],regnames[zreg]);
  1174.             if(s&2) fprintf(f,cpstr,'w',regnames[qreg],regnames[zreg]);
  1175.             if(s&1) fprintf(f,cpstr,'b',regnames[qreg],regnames[zreg]);
  1176.         }else{
  1177.             s&=3;
  1178.             while(s){fprintf(f,cpstr,'b',regnames[qreg],regnames[zreg]);s--;}
  1179.         }
  1180.         if(c==PUSH) stackoffset-=size;
  1181.     }
  1182.     return;
  1183. }
  1184. static int store_saveregs;
  1185. static void saveregs(FILE *f,struct IC *p)
  1186. {
  1187.     int dontsave;
  1188.     store_saveregs=0;
  1189.     if((p->z.flags&(REG|DREFOBJ))==REG) dontsave=p->z.reg; else dontsave=0;
  1190.     if(dontsave!= 9&®s[ 9]) {fprintf(f,"\tmove.l\td0,-(a7)\n");stackoffset-=4;store_saveregs|=1;}
  1191.     if(dontsave!=10&®s[10]) {fprintf(f,"\tmove.l\td1,-(a7)\n");stackoffset-=4;store_saveregs|=2;}
  1192.     if(dontsave!= 1&®s[ 1]) {fprintf(f,"\tmove.l\ta0,-(a7)\n");stackoffset-=4;store_saveregs|=4;}
  1193.     if(dontsave!= 2&®s[ 2]) {fprintf(f,"\tmove.l\ta1,-(a7)\n");stackoffset-=4;store_saveregs|=8;}
  1194. }
  1195. static void restoreregsa(FILE *f,struct IC *p)
  1196. {
  1197.     if(store_saveregs&8) {fprintf(f,"\tmove.l\t(a7)+,a1\n");stackoffset+=4;}
  1198.     if(store_saveregs&4) {fprintf(f,"\tmove.l\t(a7)+,a0\n");stackoffset+=4;}
  1199. }
  1200. static void restoreregsd(FILE *f,struct IC *p)
  1201. {
  1202.     int dontsave;
  1203.     if((p->z.flags&(REG|DREFOBJ))==REG) dontsave=p->z.reg; else dontsave=0;
  1204.     if(dontsave!=10&&(store_saveregs&2)) {fprintf(f,"\tmovem.l\t(a7)+,d1\n");stackoffset+=4;}
  1205.     if(dontsave!=9 &&(store_saveregs&1)) {fprintf(f,"\tmovem.l\t(a7)+,d0\n");stackoffset+=4;}
  1206. }
  1207. static int is_const(struct Typ *t)
  1208. /*  tested, ob ein Typ konstant (und damit evtl. in der Code-Section) ist   */
  1209. {
  1210.     if(!(t->flags&(CONST|STRINGCONST))){
  1211.         do{
  1212.             if(t->flags&(CONST|STRINGCONST)) return(1);
  1213.             if((t->flags&NQ)!=ARRAY) return(0);
  1214.             t=t->next;
  1215.         }while(1);
  1216.     }else return(1);
  1217. }
  1218.  
  1219.  
  1220. /****************************************/
  1221. /*  End of private fata and functions.  */
  1222. /****************************************/
  1223.  
  1224.  
  1225.  
  1226. int init_cg(void)
  1227. /*  Does necessary initializations for the code-generator. Gets called  */
  1228. /*  once at the beginning and should return 0 in case of problems.      */
  1229. {
  1230.     int i;
  1231.     larray.size=l2zl(3L);
  1232.     /*  Initialize some values which cannot be statically initialized   */
  1233.     /*  because they are stored in the target's arithmetic.             */
  1234.     maxalign=l2zl(4L);
  1235.     char_bit=l2zl(8L);
  1236.     for(i=0;i<16;i++){
  1237.         sizetab[i]=l2zl(msizetab[i]);
  1238.         align[i]=l2zl(malign[i]);
  1239.     }
  1240.     for(i= 1;i<=16;i++) {regsize[i]=l2zl( 4L);regtype[i]=<yp;}
  1241.     for(i=17;i<=24;i++) {regsize[i]=l2zl(12L);regtype[i]=&larray;}
  1242.  
  1243.     /*  default CPU is 68000    */
  1244.     if(!(g_flags[0]&USEDFLAG)) g_flags_val[0].l=68000;
  1245.     /*  no FPU by default       */
  1246.     if(!(g_flags[1]&USEDFLAG)) g_flags_val[1].l=0;
  1247.     if(g_flags_val[1].l<68000) {x_t[FLOAT]='l';}
  1248.     if(g_flags[2]&USEDFLAG) regscratch[11]=1;
  1249.     if(g_flags[3]&USEDFLAG) regsa[5]=1;
  1250.     if(g_flags[15]&USEDFLAG) dbout=1;
  1251.     if(g_flags[11]&USEDFLAG){
  1252.         gas=1;
  1253.         codename="\t.text\n";
  1254.         bssname="";
  1255.         dataname="\t.data\n";
  1256.         if(g_flags[5]&USEDFLAG) regsa[5]=1;
  1257.     }else{
  1258.         codename="\tsection\t\"CODE\",code\n";
  1259.         if(g_flags[5]&USEDFLAG){
  1260.             /*  preparing small data    */
  1261.             regsa[5]=1;
  1262.             bssname= "\tsection\t\"__MERGED\",bss\n";
  1263.             dataname="\tsection\t\"__MERGED\",data\n";
  1264.         }else{
  1265.             bssname= "\tsection\t\"BSS\",bss\n";
  1266.             dataname="\tsection\t\"DATA\",data\n";
  1267.         }
  1268.     }
  1269.     m_dataname=dataname;
  1270.     m_bssname=bssname;
  1271.     /*  a5 can be used if no framepointer is used.  */
  1272.     if(!(g_flags[8]&USEDFLAG)) regsa[6]=0;
  1273.     if(DEBUG&1) printf("CPU=%ld FPU=%ld\n",g_flags_val[0].l,g_flags_val[1].l);
  1274.  
  1275.     /*  Initialize the min/max-settings. Note that the types of the     */
  1276.     /*  host system may be different from the target system and you may */
  1277.     /*  only use the smallest maximum values ANSI guarantees if you     */
  1278.     /*  want to be portable.                                            */
  1279.     /*  That's the reason for the subtraction in t_min[INT]. Long could */
  1280.     /*  be unable to represent -2147483648 on the host system.          */
  1281.     t_min[UNSIGNED|CHAR]=t_min[UNSIGNED|SHORT]=t_min[UNSIGNED|INT]=t_min[UNSIGNED|LONG]=l2zl(0L);
  1282.     t_min[CHAR]=l2zl(-128L);
  1283.     t_min[SHORT]=l2zl(-32768L);
  1284.     t_min[INT]=zlsub(l2zl(-2147483647L),l2zl(1L));
  1285.     t_min[LONG]=t_min[INT];
  1286.     t_max[CHAR]=ul2zul(127L);
  1287.     t_max[SHORT]=ul2zul(32767UL);
  1288.     t_max[INT]=ul2zul(2147483647UL);
  1289.     t_max[LONG]=t_max[INT];
  1290.     t_max[UNSIGNED|CHAR]=ul2zul(255UL);
  1291.     t_max[UNSIGNED|SHORT]=ul2zul(65535UL);
  1292.     t_max[UNSIGNED|INT]=ul2zul(4294967295UL);
  1293.     t_max[UNSIGNED|LONG]=t_max[UNSIGNED|INT];
  1294.  
  1295.     return(1);
  1296. }
  1297.  
  1298. int freturn(struct Typ *t)
  1299. /*  Returns the register in which variables of type t are returned. */
  1300. /*  If the value cannot be returned in a register returns 0.        */
  1301. {
  1302.     long l;int tu=t->flags&NQ;
  1303.     if(tu==FLOAT){
  1304.         if(g_flags_val[1].l>=68000&&!(g_flags[13]&USEDFLAG))
  1305.             return(17);
  1306.         else
  1307.             return(9);
  1308.     }
  1309.     if(tu==DOUBLE){
  1310.         if(g_flags_val[1].l>=68000&&!(g_flags[13]&USEDFLAG)){
  1311.             return(17);
  1312.         }else{
  1313.             if(g_flags[14]&USEDFLAG) return(0);
  1314.             return(9);
  1315.         }
  1316.     }
  1317.     if(tu==STRUCT||tu==UNION){
  1318.         if(!(g_flags[14]&USEDFLAG)){
  1319.             l=zl2l(szof(t));
  1320.             if(l==4||l==8||l==12||l==16) return(9);
  1321.         }
  1322.         return(0);
  1323.     }
  1324.     if(zlleq(szof(t),l2zl(4L))) return(9); else return(0);
  1325. }
  1326.  
  1327. int regok(int r,int t,int mode)
  1328. /*  Returns 0 if register r cannot store variables of   */
  1329. /*  type t. If t==POINTER and mode!=0 then it returns   */
  1330. /*  non-zero only if the register can store a pointer   */
  1331. /*  and dereference a pointer to mode.                  */
  1332. {
  1333.     if(r==0) return(0);
  1334.     t&=NQ;
  1335.     if(t==FLOAT||t==DOUBLE){
  1336.         if(g_flags_val[1].l>=68000){
  1337.             if(r>=17&&r<=24) return(1); else return(0);
  1338.         }else{
  1339.             if(t==FLOAT&&r>=9&&r<=16) return(1); else return(0);
  1340.         }
  1341.     }
  1342.     if(t==POINTER&&mode==0&&r>=9&&r<=16) return(1);
  1343.     if(t==POINTER&&r>=1&&r<=8) return(1);
  1344.     if(t>=CHAR&&t<=LONG&&r>=9&&r<=16) return(1);
  1345.     return(0);
  1346. }
  1347.  
  1348. int dangerous_IC(struct IC *p)
  1349. /*  Returns zero if the IC p can be safely executed     */
  1350. /*  without danger of exceptions or similar things.     */
  1351. /*  vbcc may generate code in which non-dangerous ICs   */
  1352. /*  are sometimes executed although control-flow may    */
  1353. /*  never reach them (mainly when moving computations   */
  1354. /*  out of loops).                                      */
  1355. /*  Typical ICs that generate exceptions on some        */
  1356. /*  machines are:                                       */
  1357. /*      - accesses via pointers                         */
  1358. /*      - division/modulo                               */
  1359. /*      - overflow on signed integer/floats             */
  1360. {
  1361.     int c=p->code;
  1362.     if((p->q1.flags&DREFOBJ)||(p->q2.flags&DREFOBJ)||(p->z.flags&DREFOBJ))
  1363.         return(0);
  1364.     if((c==DIV||c==MOD)&&!(p->q2.flags&KONST)) return(1);
  1365.     return(0);
  1366. }
  1367.  
  1368. int must_convert(np p,int t)
  1369. /*  Returns zero if code for converting np to type t    */
  1370. /*  can be omitted.                                     */
  1371. {
  1372.     int o=p->ntyp->flags,op=o&NQ,tp=t&NQ;
  1373.     /*  All pointers have the same representation.  */
  1374.     if(tp==POINTER&&op==POINTER) return(0);
  1375.     /*  Pointer and int/long as well   */
  1376. /*    if(tp==POINTER&&(op==INT||op==LONG)) return(0);
  1377.     if(op==POINTER&&(tp==INT||tp==LONG)) return(0);*/
  1378.     /*  Signed und Unsigned integers with the same size, too.  */
  1379.     if((t&UNSIGNED)&&(o&UNSIGNED)&&zleqto(sizetab[tp],sizetab[op])) return(0);
  1380.     /*  int==long   */
  1381.     if((tp==INT&&op==LONG)||(tp==LONG&&op==INT)) return(0);
  1382.  
  1383.     /*    if((tp==FLOAT||tp==DOUBLE)&&(op==FLOAT||op==DOUBLE)&&(p->o.flags®)&&p->o.reg>=17&&p->o.reg<=24)
  1384.         return(0);*/
  1385.  
  1386.     return(1);
  1387. }
  1388.  
  1389. void gen_ds(FILE *f,zlong size,struct Typ *t)
  1390. /*  This function has to create <size> bytes of storage */
  1391. /*  initialized with zero.                              */
  1392. {
  1393.     if(gas){
  1394.         if(newobj) fprintf(f,"%ld\n",zl2l(size));
  1395.             else   fprintf(f,"\t.space\t%ld\n",zl2l(size));
  1396.         newobj=0;
  1397.     }else{
  1398.         if(section!=BSS&&newobj){fprintf(f,bssname);section=BSS;}
  1399.         fprintf(f,"\tds.b\t%ld\n",zl2l(size));newobj=0;
  1400.     }
  1401. }
  1402.  
  1403. void gen_align(FILE *f,zlong align)
  1404. /*  This function has to make sure the next data is     */
  1405. /*  aligned to multiples of <align> bytes.              */
  1406. {
  1407.     if(align>1){
  1408.         if(gas){
  1409.             fprintf(f,"\t.align\t4\n");
  1410.         }else{
  1411.             fprintf(f,"\tcnop\t0,4\n");
  1412.         }
  1413.     }
  1414. }
  1415. void gen_var_head(FILE *f,struct Var *v)
  1416. /*  This function has to create the head of a variable  */
  1417. /*  definition, i.e. the label and information for      */
  1418. /*  linkage etc.                                        */
  1419. {
  1420.     int constflag;
  1421.     if(v->clist) constflag=is_const(v->vtyp);
  1422.     if(v->tattr&5){
  1423.       if(v->tattr&4){
  1424.         dataname="\tsection\t\"CHIP_DATA\",data,chip\n";
  1425.         bssname="\tsection\t\"CHIP_BSS\",bss,chip\n";
  1426.       }else{
  1427.         dataname="\tsection\t\"DATA\",data\n";
  1428.         bssname="\tsection\t\"BSS\",bss\n";
  1429.       }
  1430.       section=-1;
  1431.     }else{
  1432.       dataname=m_dataname;
  1433.       bssname=m_bssname;
  1434.     }
  1435.     if(v->storage_class==STATIC){
  1436.       if((v->vtyp->flags&NQ)==FUNKT) return;
  1437.       if(v->clist&&(!constflag||(g_flags[7]&USEDFLAG))&§ion!=DATA){fprintf(f,dataname);section=DATA;}
  1438.       if(v->clist&&constflag&&!(g_flags[7]&USEDFLAG)&§ion!=CODE){fprintf(f,codename);section=CODE;}
  1439.       if(!v->clist&§ion!=BSS){fprintf(f,bssname);section=BSS;}
  1440.       if(gas){
  1441.         if(section!=BSS) fprintf(f,"\t.align\t4\nl%ld:\n",zl2l(v->offset));
  1442.         else fprintf(f,"\t.lcomm\tl%ld,",zl2l(v->offset));
  1443.       }else{
  1444.         fprintf(f,"\tcnop\t0,4\nl%ld\n",zl2l(v->offset));
  1445.       }
  1446.       newobj=1;
  1447.     }
  1448.     if(v->storage_class==EXTERN){
  1449.       if(gas){
  1450.         fprintf(f,"\t.global\t_%s\n",v->identifier);
  1451.       }else{
  1452.         fprintf(f,"\tpublic\t_%s\n",v->identifier);
  1453.       }
  1454.       if(v->flags&(DEFINED|TENTATIVE)){
  1455.         if(v->clist&&(!constflag||(g_flags[7]&USEDFLAG))&§ion!=DATA){fprintf(f,dataname);section=DATA;}
  1456.         if(v->clist&&constflag&&!(g_flags[7]&USEDFLAG)&§ion!=CODE){fprintf(f,codename);section=CODE;}
  1457.         if(!v->clist&§ion!=BSS){fprintf(f,bssname);section=BSS;}
  1458.         if(gas){
  1459.           if(section!=BSS)
  1460.             fprintf(f,"\t.align\t4\n_%s:\n",v->identifier);
  1461.           else
  1462.             fprintf(f,"\t.comm\t_%s,",v->identifier);
  1463.         }else{
  1464.           fprintf(f,"\tcnop\t0,4\n_%s\n",v->identifier);
  1465.         }
  1466.         newobj=1;
  1467.       }
  1468.     }
  1469.     if(v->tattr&5) {section=-1;newobj=0;}
  1470. }
  1471. void gen_dc(FILE *f,int t,struct const_list *p)
  1472. /*  This function has to create static storage          */
  1473. /*  initialized with const-list p.                      */
  1474. {
  1475.     char s;
  1476.     if(!p){ierror(0);return;}
  1477. /*    if(section!=DATA){fprintf(f,dataname);section=DATA;}*/
  1478.     if((t&NQ)==FLOAT||(t&NQ)==DOUBLE) s='l'; else s=x_t[t&NQ];
  1479.     if(gas){
  1480.         char *str;
  1481.         if(s=='b') str="\t.byte\t";
  1482.         else if(s=='w') str="\t.short\t";
  1483.         else if(s=='l') str="\t.long\t";
  1484.         else ierror(0);
  1485.         fprintf(f,"%s",str);
  1486.     }else{
  1487.         fprintf(f,"\tdc.%c\t",s);
  1488.     }
  1489.     if(!p->tree){
  1490.         if((t&NQ)==FLOAT||(t&NQ)==DOUBLE){
  1491.         /*  auch wieder nicht sehr schoen und IEEE noetig   */
  1492.             unsigned char *ip;char *s;
  1493.             ip=(unsigned char *)&p->val.vdouble;
  1494.             if(gas) s="0x"; else s="$";
  1495.             fprintf(f,"%s%02x%02x%02x%02x",s,ip[0],ip[1],ip[2],ip[3]);
  1496.             if((t&NQ)==DOUBLE){
  1497.                 fprintf(f,",%s%02x%02x%02x%02x",s,ip[4],ip[5],ip[6],ip[7]);
  1498.             }
  1499.         }else{
  1500.             printval(f,&p->val,t&NU,0);
  1501.         }
  1502.     }else{
  1503.         int m,m2;
  1504.         p->tree->o.am=0;
  1505.         m=p->tree->o.flags;
  1506.         p->tree->o.flags&=~VARADR;
  1507.         m2=g_flags[5];
  1508.         g_flags[5]&=~USEDFLAG;
  1509.         probj2(f,&p->tree->o,t&NU);
  1510.         p->tree->o.flags=m;
  1511.         g_flags[5]=m2;
  1512.     }
  1513.     fprintf(f,"\n");newobj=0;
  1514. }
  1515.  
  1516. /*  The main code-generation routine.                   */
  1517. /*  f is the stream the code should be written to.      */
  1518. /*  p is a pointer to a doubly linked list of ICs       */
  1519. /*  containing the function body to generate code for.  */
  1520. /*  v is a pointer to the function.                     */
  1521. /*  offset is the size of the stackframe the function   */
  1522. /*  needs for local variables.                          */
  1523.  
  1524. void gen_code(FILE *f,struct IC *p,struct Var *v,zlong offset)
  1525. {
  1526.     int c,t,comptyp;char fp[2]="\0\0";
  1527.     int act_line=0;char *act_file=0;
  1528.     if(DEBUG&1) printf("gen_code()\n");
  1529.     for(c=1;c<=MAXR;c++) regs[c]=regsa[c];
  1530.     if(!(g_flags[9]&USEDFLAG)){
  1531.     /*  Adressierungsarten benutzen */
  1532.         if(!addressing()) offset=l2zl(0L);
  1533.     }
  1534.     if(dbout){
  1535.         if(!gas){
  1536.             act_line=fline;
  1537.             fprintf(f,"\tdsource\t\"%s\"\n",errfname);
  1538.             fprintf(f,"\tdebug\t%d\n",act_line);
  1539.         }
  1540.     }
  1541.     reglabel=++label;freglabel=++label;
  1542.     function_top(f,v,zl2l(offset));
  1543.     if(p!=first_ic) ierror(0);
  1544.     cc_set=cc_set_tst=0;
  1545.     stackoffset=notpopped=dontpop=0;
  1546.     for(;p;pr(f,p),p=p->next){
  1547.         if(dbout){
  1548.         /*  Hier soll spaeter mal das Sourcefile angegeben werden.  */
  1549.             if(p->file&&p->file!=act_file) ierror(0);
  1550.             if(p->line&&p->line!=act_line){
  1551.                 act_line=p->line;
  1552.                 if(!gas) fprintf(f,"\tdebug\t%d\n",act_line);
  1553.             }
  1554.         }
  1555.         c=p->code;t=p->typf;
  1556.         if(c==NOP) continue;
  1557.         cc_set_tst=cc_set;
  1558.         cc_typ_tst=cc_typ;
  1559.         if(cc_set_tst&&(DEBUG&512)){fprintf(f,"; cc_set_tst=");probj2(f,cc_set_tst,t);fprintf(f,"\n");}
  1560.         if(cc_set&&(DEBUG&512)){fprintf(f,"; cc_set=");probj2(f,cc_set,t);fprintf(f,"\n");}
  1561.         pushedreg&=16;if(c==RESTOREREGS) pushedreg=0;
  1562.         if(DEBUG&256){fprintf(f,"; "); pric2(f,p);}
  1563.         if(DEBUG&512) fprintf(f,"; stackoffset=%ld, notpopped=%ld, pushedreg=%d, dontpop=%ld\n",stackoffset,notpopped,pushedreg,dontpop);
  1564.         /*  muessen wir Argumente poppen?   */
  1565.         if(notpopped&&!dontpop){
  1566.             int flag=0;
  1567.             if(c==LABEL||c==COMPARE||c==TEST||c==BRA){
  1568.                 fprintf(f,"\tadd%s.%s\t#%ld,a7\n",quick[notpopped<=8],strshort[notpopped<32768],notpopped);
  1569.                 stackoffset+=notpopped;notpopped=0;/*cc_set_tst=cc_set=0;*/
  1570.             }
  1571.         }
  1572.         /*  na, ob das hier ok ist..?   */
  1573.         if(c==SUBPFP) c=SUB;
  1574.         if(c==PMULT) c=MULT;
  1575.         if(c==ALLOCREG) {regs[p->q1.reg]=1;continue;}
  1576.         if(c==FREEREG) {regs[p->q1.reg]=0;continue;}
  1577.         if(c==LABEL){
  1578.             if(dbout) act_line=0;
  1579.             if(gas){
  1580.                 fprintf(f,"l%d:\n",t);
  1581.             }else{
  1582.                 fprintf(f,"l%d\n",t);
  1583.             }
  1584.             cc_set=0;continue;
  1585.         }
  1586.         if(c==BRA){fprintf(f,"\t%sbra\tl%d\n",(gas?"j":""),t);continue;}
  1587.         if(c>=BEQ&&c<BRA){
  1588.             if(gas){
  1589.                 if(stored_cc){fprintf(f,"\tjne\tl%d\n",t);stored_cc=0;continue;}
  1590.                 if((comptyp&UNSIGNED)||(comptyp&NQ)==POINTER){
  1591.                     fprintf(f,"\tj%s\tl%d\n",ubranch[c-BEQ],t);
  1592.                 }else{
  1593.                     fprintf(f,"\t%sj%s\tl%d\n",fp,ename[c]+1,t);
  1594.                 }
  1595.             }else{
  1596.                 if(stored_cc){fprintf(f,"\tbne\tl%d\n",t);stored_cc=0;continue;}
  1597.                 if((comptyp&UNSIGNED)||(comptyp&NQ)==POINTER){
  1598.                     fprintf(f,"\tb%s\tl%d\n",ubranch[c-BEQ],t);
  1599.                 }else{
  1600.                     fprintf(f,"\t%s%s\tl%d\n",fp,ename[c],t);
  1601.                 }
  1602.             }
  1603.             continue;
  1604.         }
  1605.         if(p->q1.am){
  1606.             if(!regs[p->q1.am->basereg]){pric2(stdout,p);printf("%s\n",regnames[p->q1.am->basereg]); ierror(0);}
  1607.             if(p->q1.am->dreg&&!regs[p->q1.am->dreg&127]) {printf("Register %s:\n",regnames[p->q1.am->dreg&127]);ierror(0);}
  1608.         }
  1609.         if(p->q2.am){
  1610.             if(!regs[p->q2.am->basereg]) ierror(0);
  1611.             if(p->q2.am->dreg&&!regs[p->q2.am->dreg&127]) {printf("Register %s:\n",regnames[p->q2.am->dreg&127]);ierror(0);}
  1612.         }
  1613.         if(p->z.am){
  1614.             if(!regs[p->z.am->basereg]) ierror(0);
  1615.             if(p->z.am->dreg&&!regs[p->z.am->dreg&127]) {printf("Register %s:\n",regnames[p->z.am->dreg&127]);ierror(0);}
  1616.         }
  1617.         if((p->q1.flags®)&&!regs[p->q1.reg]){printf("Register %s:\n",regnames[p->q1.reg]);ierror(0);}
  1618.         if((p->q2.flags®)&&!regs[p->q2.reg]){printf("Register %s:\n",regnames[p->q2.reg]);ierror(0);}
  1619.         if((p->z.flags®)&&!regs[p->z.reg]){printf("Register %s:\n",regnames[p->z.reg]);ierror(0);}
  1620.         if((p->q2.flags®)&&(p->z.flags®)&&p->q2.reg==p->z.reg){pric2(stdout,p);ierror(0);}
  1621.         if((p->q2.flags&VAR)&&(p->z.flags&VAR)&&p->q2.v==p->z.v&&compare_objects(&p->q2,&p->z)){pric2(stdout,p);ierror(0);}
  1622.         /*  COMPARE #0 durch TEST ersetzen (erlaubt, da tst alle Flags setzt)   */
  1623.         if(c==COMPARE&&(p->q2.flags&KONST)){
  1624.             eval_const(&p->q2.val,t);
  1625.             if(zleqto(l2zl(0L),vlong)&&zuleqto(ul2zul(0UL),vulong)&&zdeqto(d2zd(0.0),vdouble)){
  1626.                 c=p->code=TEST;p->q2.flags=0;
  1627.             }
  1628.         }
  1629.         if(c==COMPARE&&(p->q1.flags&KONST)){
  1630.             eval_const(&p->q1.val,t);
  1631.             if(zleqto(l2zl(0L),vlong)&&zuleqto(ul2zul(0UL),vulong)&&zdeqto(d2zd(0.0),vdouble)){
  1632.                 struct IC *bp=p->next;int bc;
  1633.                 c=p->code=TEST;p->q1=p->q2;p->q2.flags=0;p->q2.am=0;
  1634.                 /*  Nachfolgenden Branch umdrehen   */
  1635.                 while(bp&&bp->code==FREEREG) bp=bp->next;
  1636.                 bc=bp->code;
  1637.                 if(!bp||bc<BEQ||bc>BGT) ierror(0);
  1638.                 if(bc==BLT) bp->code=BGT;
  1639.                 if(bc==BGT) bp->code=BLT;
  1640.                 if(bc==BLE) bp->code=BGE;
  1641.                 if(bc==BGE) bp->code=BLE;
  1642.             }
  1643.         }
  1644.         /*  gesetzte ConditionCodes merken  */
  1645.         if(p->z.flags&&(!isreg(z)||p->z.reg>=9)&&c!=CONVFLOAT&&c!=CONVDOUBLE&&(((t&NQ)!=FLOAT&&(t&NQ)!=DOUBLE)||g_flags_val[1].l>68000)){
  1646.              cc_set=&p->z;cc_typ=p->typf;
  1647.         }else{
  1648.             cc_set=0;
  1649.         }
  1650.         if(c==PEA){
  1651.             fprintf(f,"\tpea\t");probj2(f,&p->q1,t);fprintf(f,"\n");
  1652.             stackoffset-=zl2l(p->q2.val.vlong);
  1653.             dontpop+=zl2l(p->q2.val.vlong);
  1654.             continue;
  1655.         }
  1656.         if(c==MOVEFROMREG){
  1657.             if(p->q1.reg<17) fprintf(f,"\tmove.l\t%s,",regnames[p->q1.reg]);
  1658.                 else         fprintf(f,"\tfmove.x\t%s,",regnames[p->q1.reg]);
  1659.             probj2(f,&p->z,t);fprintf(f,"\n");
  1660.             continue;
  1661.         }
  1662.         if(c==MOVETOREG){
  1663.             if(p->z.reg<17) fprintf(f,"\tmove.l\t");
  1664.                 else        fprintf(f,"\tfmove.x\t");
  1665.             probj2(f,&p->q1,t);fprintf(f,",%s\n",regnames[p->z.reg]);
  1666.             continue;
  1667.         }
  1668.         if(g_flags[9]&USEDFLAG)
  1669.             if(p->q1.am||p->q2.am||p->z.am){
  1670.                 ierror(0);
  1671.                 p->q1.am=p->q2.am=p->z.am=0;
  1672.             }
  1673.         p=do_refs(f,p);
  1674.         if(g_flags[9]&USEDFLAG)
  1675.             if(p->q1.am||p->q2.am||p->z.am){
  1676.                 ierror(0);
  1677.                 p->q1.am=p->q2.am=p->z.am=0;
  1678.             }
  1679.         if(c>=CONVCHAR&&c<=CONVULONG){
  1680.             int to;
  1681.             if((t&NQ)==POINTER) t=(UNSIGNED|LONG);
  1682.             if(c==CONVCHAR) to=CHAR;
  1683.             if(c==CONVUCHAR) to=(UNSIGNED|CHAR);
  1684.             if(c==CONVSHORT) to=SHORT;
  1685.             if(c==CONVUSHORT) to=(UNSIGNED|SHORT);
  1686.             if(c==CONVINT) to=LONG;
  1687.             if(c==CONVUINT) to=(UNSIGNED|LONG);
  1688.             if(c==CONVLONG) to=LONG;
  1689.             if(c==CONVULONG) to=(UNSIGNED|LONG);
  1690.             if(c==CONVFLOAT) to=FLOAT;
  1691.             if(c==CONVDOUBLE) to=DOUBLE;
  1692.             if(c==CONVPOINTER) to=(UNSIGNED|LONG);
  1693.             if(c==CONVVOID){ierror(0);continue;}
  1694.             if(t==FLOAT||t==DOUBLE||to==FLOAT||to==DOUBLE){
  1695.                 if(g_flags_val[1].l>=68000){
  1696.                     int zreg=0;
  1697.                     if((t==FLOAT||t==DOUBLE)&&(to==FLOAT||to==DOUBLE)){
  1698.                         if(isreg(q1)&&isreg(z)){
  1699.                             if(p->q1.reg!=p->z.reg)
  1700.                                 fprintf(f,"\tfmove.x\t%s,%s\n",regnames[p->q1.reg],regnames[p->z.reg]);
  1701.                             continue;
  1702.                         }
  1703.                     }
  1704.                     if(isreg(z)&&p->z.reg>=17)
  1705.                         zreg=p->z.reg;
  1706.                     if(isreg(q1)&&p->q1.reg>=17){
  1707.                         if(!zreg) zreg=p->q1.reg; else zreg=get_reg(f,2,p);}
  1708.                     if(!zreg) zreg=get_reg(f,2,p);
  1709.                     if((to&UNSIGNED)&&x_t[to&NQ]!='l'){
  1710.                         int dreg=get_reg(f,1,p);
  1711.                         fprintf(f,"\tmoveq\t#0,%s\n",regnames[dreg]);
  1712.                         move(f,&p->q1,0,0,dreg,to);
  1713.                         move(f,0,dreg,0,zreg,LONG);
  1714.                     }else{
  1715.                         if(!isreg(q1)||p->q1.reg!=zreg)
  1716.                             move(f,&p->q1,0,0,zreg,to);
  1717.                     }
  1718.                     if(t!=FLOAT&&t!=DOUBLE){
  1719.                     /*  nach integer, d.h. Kommastellen abschneiden */
  1720.                         if(g_flags_val[1].l==68040/*||g_flags_val[1].l==68060*/){
  1721.                         /*  bei 040 emuliert    */
  1722.                             int dreg1=get_reg(f,1,p),dreg2=get_reg(f,1,p);
  1723.                             fprintf(f,"\tfmove.l\tfpcr,%s\n",regnames[dreg2]);
  1724.                             fprintf(f,"\tmoveq\t#16,%s\n",regnames[dreg1]);
  1725.                             fprintf(f,"\tor.l\t%s,%s\n",regnames[dreg2],regnames[dreg1]);
  1726.                             fprintf(f,"\tand.w\t#-33,%s\n",regnames[dreg1]);
  1727.                             fprintf(f,"\tfmove.l\t%s,fpcr\n",regnames[dreg1]);
  1728.                             if((t&UNSIGNED)&&(t&NQ)<INT){
  1729.                                 fprintf(f,"\tfmove.l\t%s,%s\n",regnames[zreg],regnames[dreg1]);
  1730.                                 fprintf(f,"\tmove.%c\t%s,",x_t[t&NQ],regnames[dreg1]);
  1731.                             }else{
  1732.                                 fprintf(f,"\tfmove.%c\t%s,",x_t[t&NQ],regnames[zreg]);
  1733.                             }
  1734.                             probj2(f,&p->z,t);fprintf(f,"\n");
  1735.                             fprintf(f,"\tfmove.l\t%s,fpcr\n",regnames[dreg2]);
  1736.                             continue;
  1737.                         }else{
  1738.                             if(!isreg(q1)||p->q1.reg!=zreg){
  1739.                                 fprintf(f,"\tfintrz.x\t%s\n",regnames[zreg]);
  1740.                             }else{
  1741.                                 int nreg=get_reg(f,2,p);
  1742.                                 fprintf(f,"\tfintrz.x\t%s,%s\n",regnames[zreg],regnames[nreg]);
  1743.                                 zreg=nreg;
  1744.                             }
  1745.                             if((t&UNSIGNED)&&(t&NQ)<INT){
  1746.                                 int r;
  1747.                                 if(isreg(z)) r=p->z.reg; else r=get_reg(f,1,p);
  1748.                                 move(f,0,zreg,0,r,LONG);
  1749.                                 move(f,0,r,&p->z,0,t);
  1750.                             }else{
  1751.                                 move(f,0,zreg,&p->z,0,t);
  1752.                             }
  1753.                             continue;
  1754.                         }
  1755.                     }
  1756.                     if(to&UNSIGNED&&x_t[to&NQ]=='l'){
  1757.                         int nlabel;
  1758.                         fprintf(f,"\ttst.%c\t",x_t[to&NQ]);
  1759.                         probj2(f,&p->q1,to);fprintf(f,"\n");
  1760.                         nlabel=++label;
  1761.                         fprintf(f,"\tbge.s\tl%d\n",nlabel);
  1762.                         fprintf(f,"\tfadd.d\t#4294967296,%s\n",regnames[zreg]);
  1763.                         fprintf(f,"l%d:\n",nlabel);
  1764.                     }
  1765.                     if(!(p->z.reg)||p->z.reg!=zreg){
  1766.                         move(f,0,zreg,&p->z,0,t);
  1767.                     }
  1768.                 }else{
  1769.                     cc_set=0;
  1770.                     if(to==t){
  1771.                         assign(f,p,&p->q1,&p->z,ASSIGN,zl2l(p->q2.val.vlong),t);
  1772.                         continue;
  1773.                     }
  1774.                     if(to==FLOAT&&t==DOUBLE){
  1775.                         saveregs(f,p);
  1776.                         assign(f,p,&p->q1,0,PUSH,msizetab[FLOAT],FLOAT);
  1777.                         if(gas){
  1778.                             fprintf(f,"\t.global\t__ieees2d\n\tjbsr\t__ieees2d\n\taddq.w\t#4,a7\n");
  1779.                         }else{
  1780.                             fprintf(f,"\tpublic\t__ieees2d\n\tjsr\t__ieees2d\n\taddq.w\t#4,a7\n");
  1781.                         }
  1782.                         stackoffset+=4;
  1783.                         restoreregsa(f,p);
  1784.                         fprintf(f,"\tmovem.l\td0/d1,");
  1785.                         probj2(f,&p->z,t);fprintf(f,"\n");
  1786.                         restoreregsd(f,p);
  1787.                         continue;
  1788.                     }
  1789.                     if(to==DOUBLE&&t==FLOAT){
  1790.                         saveregs(f,p);
  1791.                         assign(f,p,&p->q1,0,PUSH,msizetab[DOUBLE],DOUBLE);
  1792.                         if(gas){
  1793.                             fprintf(f,"\t.global\t__ieeed2s\n\tjbsr\t__ieeed2s\n\taddq.w\t#8,a7\n");
  1794.                         }else{
  1795.                             fprintf(f,"\tpublic\t__ieeed2s\n\tjsr\t__ieeed2s\n\taddq.w\t#8,a7\n");
  1796.                         }
  1797.                         stackoffset+=8;
  1798.                         restoreregsa(f,p);
  1799.                         move(f,0,9,&p->z,0,t);
  1800.                         restoreregsd(f,p);
  1801.                         continue;
  1802.                     }
  1803.                     if(to==FLOAT||to==DOUBLE){
  1804.                         int uns;
  1805.                         saveregs(f,p);
  1806.                         if(t&UNSIGNED) uns='u'; else uns='s';
  1807.                         assign(f,p,&p->q1,0,PUSH,sizetab[to&NQ],to);
  1808.                         if(gas){
  1809.                             fprintf(f,"\t.global\t__ieeefix%c%c\n\tjbsr\t__ieeefix%c%c\n\taddq.w\t#%ld,a7\n",x_t[to&NQ],uns,x_t[to&NQ],uns,zl2l(sizetab[to&NQ]));
  1810.                         }else{
  1811.                             fprintf(f,"\tpublic\t__ieeefix%c%c\n\tjsr\t__ieeefix%c%c\n\taddq.w\t#%ld,a7\n",x_t[to&NQ],uns,x_t[to&NQ],uns,zl2l(sizetab[to&NQ]));
  1812.                         }
  1813.                         stackoffset+=sizetab[to&NQ];
  1814.                         restoreregsa(f,p);
  1815.                         move(f,0,9,&p->z,0,t);
  1816.                         restoreregsd(f,p);
  1817.                         continue;
  1818.                     }else{
  1819.                         int uns,xt=x_t[to&NQ];
  1820.                         saveregs(f,p);
  1821.                         if(to&UNSIGNED) uns='u'; else uns='s';
  1822.                         if(xt!='l') {fprintf(f,"\tsubq.w\t#4,a7\n");stackoffset-=4;}
  1823.                         fprintf(f,"\tmove.%c\t",xt);
  1824.                         probj2(f,&p->q1,to);
  1825.                         if(xt!='l') fprintf(f,",(a7)\n"); else {fprintf(f,",-(a7)\n");stackoffset-=4;}
  1826.                         if(gas){
  1827.                             fprintf(f,"\t.global\t__ieeeflt%c%c%c\n\tjbsr\t__ieeeflt%c%c%c\n\taddq.w\t#4,a7\n",uns,xt,x_t[t&NQ],uns,xt,x_t[t&NQ]);
  1828.                         }else{
  1829.                             fprintf(f,"\tpublic\t__ieeeflt%c%c%c\n\tjsr\t__ieeeflt%c%c%c\n\taddq.w\t#4,a7\n",uns,xt,x_t[t&NQ],uns,xt,x_t[t&NQ]);
  1830.                         }
  1831.                         stackoffset+=4;
  1832.                         restoreregsa(f,p);
  1833.                         if(t==DOUBLE){
  1834.                             fprintf(f,"\tmovem.l\td0/d1,");
  1835.                             probj2(f,&p->z,t);fprintf(f,"\n");
  1836.                         }else move(f,0,9,&p->z,0,t);
  1837.                         restoreregsd(f,p);
  1838.                         continue;
  1839.                     }
  1840.                 }
  1841.                 continue;
  1842.             }
  1843.             if((to&NQ)<(t&NQ)){
  1844.                 int zreg;
  1845.                 if(isreg(z)&&p->z.reg>=9&&p->z.reg<=16)
  1846.                     zreg=p->z.reg; else zreg=get_reg(f,1,p);
  1847.                 /*  aufpassen, falls unsigned und Quelle==Ziel  */
  1848.                 if((to&UNSIGNED)&&isreg(q1)&&zreg==p->q1.reg){
  1849.                     unsigned long l;
  1850.                     if((to&NQ)==CHAR) l=0xff; else l=0xffff;
  1851.                     fprintf(f,"\tand.%c\t#%lu,%s\n",x_t[t&NQ],l,regnames[zreg]);
  1852.                     continue;
  1853.                 }
  1854.                 if(to&UNSIGNED) fprintf(f,"\tmoveq\t#0,%s\n",regnames[zreg]);
  1855.                 move(f,&p->q1,0,0,zreg,to);
  1856.                 if(!(to&UNSIGNED)){
  1857.                     if((to&NQ)==CHAR&&(t&NQ)==SHORT) fprintf(f,"\text.w\t%s\n",regnames[zreg]);
  1858.                     if((to&NQ)==SHORT&&msizetab[t&NQ]==4) fprintf(f,"\text.l\t%s\n",regnames[zreg]);
  1859.                     if((to&NQ)==CHAR&&msizetab[t&NQ]==4){
  1860.                         if(g_flags_val[0].l>=68020)
  1861.                             fprintf(f,"\textb.l\t%s\n",regnames[zreg]);
  1862.                         else
  1863.                             fprintf(f,"\text.w\t%s\n\text.l\t%s\n",regnames[zreg],regnames[zreg]);
  1864.                     }
  1865.                 }
  1866.                 if(!isreg(z)||p->z.reg!=zreg){
  1867.                     move(f,0,zreg,&p->z,0,t);
  1868.                 }
  1869.             }else{
  1870.                 long diff;int m;
  1871.                 m=0;
  1872.                 if(p->q1.flags®){
  1873.                     p->q1.val.vlong=l2zl(0L);
  1874.                     p->q1.flags|=D16OFF;m=1;
  1875.                 }
  1876.                 diff=msizetab[to&NQ]-msizetab[t&NQ];
  1877.                 vlong=l2zl(diff);
  1878.                 p->q1.val.vlong=zladd(p->q1.val.vlong,vlong);
  1879.                 move(f,&p->q1,0,&p->z,0,t);
  1880.                 vlong=l2zl(diff);
  1881.                 p->q1.val.vlong=zlsub(p->q1.val.vlong,vlong);
  1882.                 if(m) p->q1.flags&=~D16OFF;
  1883.             }
  1884.             continue;
  1885.         }
  1886.         if((t==FLOAT||t==DOUBLE)&&g_flags_val[1].l>=68000) *fp='f'; else *fp=0;
  1887.         if(c==MINUS||c==KOMPLEMENT){
  1888.             int zreg;
  1889.             if(t==FLOAT||t==DOUBLE){
  1890.                 if(g_flags_val[1].l>=68000){
  1891.                     if(isreg(z)) zreg=p->z.reg; else zreg=get_reg(f,2,p);
  1892.                     fprintf(f,"\tfneg.");
  1893.                     if(isreg(q1)) fprintf(f,"x\t%s",regnames[p->q1.reg]);
  1894.                         else    {fprintf(f,"%c\t",x_t[t&NQ]);probj2(f,&p->q1,t);}
  1895.                     fprintf(f,",%s\n",regnames[zreg]);
  1896.                     if(!isreg(z)||p->z.reg!=zreg){
  1897.                         move(f,0,zreg,&p->z,0,t);
  1898.                     }
  1899.                     continue;
  1900.                 }else{
  1901.                     saveregs(f,p);
  1902.                     assign(f,p,&p->q1,0,PUSH,msizetab[t&NQ],t);
  1903.                     if(gas){
  1904.                         fprintf(f,"\t.global\t__ieeeneg%c\n\tjbsr\t__ieeeneg%c\n\taddq.w\t#%ld,a7\n",x_t[t&NQ],x_t[t&NQ],msizetab[t&NQ]);
  1905.                     }else{
  1906.                         fprintf(f,"\tpublic\t__ieeeneg%c\n\tjsr\t__ieeeneg%c\n\taddq.w\t#%ld,a7\n",x_t[t&NQ],x_t[t&NQ],msizetab[t&NQ]);
  1907.                     }
  1908.                     stackoffset+=msizetab[t&NQ];
  1909.                     restoreregsa(f,p);
  1910.                     if(t==DOUBLE){
  1911.                         fprintf(f,"\tmovem.l\td0/d1,");
  1912.                         probj2(f,&p->z,t);fprintf(f,"\n");
  1913.                     }else move(f,0,9,&p->z,0,t);
  1914.                     restoreregsd(f,p);
  1915.                     continue;
  1916.                 }
  1917.             }
  1918.             if(compare_objects(&p->q1,&p->z)){
  1919.                 fprintf(f,"\t%s.%c\t",ename[c],x_t[t&NQ]);
  1920.                 probj2(f,&p->q1,t);fprintf(f,"\n");
  1921.                 continue;
  1922.             }
  1923.             if(isreg(z)&&p->z.reg>=9/*&&p->z.reg<=16*/)
  1924.                 zreg=p->z.reg; else zreg=get_reg(f,1,p);
  1925.             if(!isreg(q1)||p->q1.reg!=zreg){
  1926.                 move(f,&p->q1,0,0,zreg,t);
  1927.             }
  1928.             fprintf(f,"\t%s.%c\t%s\n",ename[c],x_t[t&NQ],regnames[zreg]);
  1929.             if(!isreg(z)||p->z.reg!=zreg){
  1930.                 move(f,0,zreg,&p->z,0,t);
  1931.             }
  1932.             continue;
  1933.         }
  1934.         if(c==SETRETURN){
  1935.         /*  Returnwert setzen - q2.val.vlong==size, z.reg==Returnregister */
  1936.             if((t&NQ)==DOUBLE&&p->z.reg==9){
  1937.                 if(p->q1.flags&KONST){
  1938.                     unsigned char *ip=(unsigned char *)&p->q1.val.vdouble;
  1939.                     char *s;
  1940.                     if(gas) s="0x"; else s="$";
  1941.                     fprintf(f,"\tmove.l\t#%s%02x%02x%02x%02x,d0\n",s,ip[0],ip[1],ip[2],ip[3]);
  1942.                     fprintf(f,"\tmove.l\t#%s%02x%02x%02x%02x,d1\n",s,ip[4],ip[5],ip[6],ip[7]);
  1943.                     continue;
  1944.                 }
  1945.                 if(isreg(q1)){
  1946.                     fprintf(f,"\tfmove.d\t%s,-(a7)\n\tmovem.l\t(a7)+",regnames[p->q1.reg]);
  1947.                 }else{
  1948.                     fprintf(f,"\tmovem.l\t");probj2(f,&p->q1,t);
  1949.                 }
  1950.                 fprintf(f,",d0/d1\n");
  1951.                 continue;
  1952.             }
  1953.             if(((t&NQ)==STRUCT||(t&NQ)==UNION)&&p->z.reg==9){
  1954.                 long l=zl2l(p->q2.val.vlong);
  1955.                 fprintf(f,"\tmovem.l\t");probj2(f,&p->q1,t);
  1956.                 fprintf(f,",d0");
  1957.                 if(l>=8) fprintf(f,"/d1");
  1958.                 if(l>=12) fprintf(f,"/a0");
  1959.                 if(l>=16) fprintf(f,"/a1");
  1960.                 fprintf(f,"\n");
  1961.                 continue;
  1962.             }
  1963.         /*  Wenn Returnwert ueber Zeiger gesetzt wird, nichts noetig    */
  1964.             if(p->z.reg) move(f,&p->q1,0,0,p->z.reg,p->typf);
  1965.             continue;
  1966.         }
  1967.         if(c==GETRETURN){
  1968.         /*  Returnwert holen - q2.val.vlong==size, q1.reg==Returnregister     */
  1969.             if((t&NQ)==DOUBLE&&p->q1.reg==9){
  1970.                 fprintf(f,"\tmovem.l\td0/d1");
  1971.                 if(isreg(z)){
  1972.                     fprintf(f,",-(a7)\n\tfmove.d\t(a7)+,%s\n",regnames[p->z.reg]);
  1973.                 }else{
  1974.                     fprintf(f,",");probj2(f,&p->z,t);fprintf(f,"\n");
  1975.                 }
  1976.                 continue;
  1977.             }
  1978.             if(((t&NQ)==STRUCT||(t&NQ)==UNION)&&p->q1.reg==9){
  1979.                 long l=zl2l(p->q2.val.vlong);
  1980.                 fprintf(f,"\tmovem.l\t");
  1981.                 fprintf(f,"d0");
  1982.                 if(l>=8) fprintf(f,"/d1");
  1983.                 if(l>=12) fprintf(f,"/a0");
  1984.                 if(l>=16) fprintf(f,"/a1");
  1985.                 fprintf(f,",");probj2(f,&p->z,t);fprintf(f,"\n");
  1986.                 continue;
  1987.             }
  1988.  
  1989.         /*  Wenn Returnwert ueber Zeiger gesetzt wird, nichts noetig    */
  1990.             cc_set=0;
  1991.             if(p->q1.reg){
  1992.                 move(f,0,p->q1.reg,&p->z,0,p->typf);
  1993.                 if(!(p->z.flags®)||(p->z.reg!=p->q1.reg&&p->z.reg>=9)){ cc_set=&p->z;cc_typ=p->typf;}
  1994.             }
  1995.             continue;
  1996.         }
  1997.         if(c==CALL){
  1998.           if((p->q1.flags&VAR)&&p->q1.v->fi&&p->q1.v->fi->inline_asm){
  1999.             fprintf(f,"%s\n",p->q1.v->fi->inline_asm);
  2000.           }else{
  2001.             if(gas){
  2002.               fprintf(f,"\tjbsr\t");
  2003.             }else{
  2004.               fprintf(f,"\tjsr\t");
  2005.             }
  2006.             /*  Wenn geta4() aufgerufen wurde, merken.  */
  2007.             if((p->q1.flags&(VAR|DREFOBJ))==VAR&&!strcmp(p->q1.v->identifier,"geta4")&&p->q1.v->storage_class==EXTERN)
  2008.               geta4=1;
  2009.             if((p->q1.flags&(DREFOBJ|REG))==DREFOBJ) ierror(0);
  2010.             probj2(f,&p->q1,t);
  2011.             fprintf(f,"\n");
  2012.           }
  2013.           if(dbout) act_line=0;
  2014.           if(zl2l(p->q2.val.vlong)){
  2015.             notpopped+=zl2l(p->q2.val.vlong);
  2016.             dontpop-=zl2l(p->q2.val.vlong);
  2017.             if(!(g_flags[10]&USEDFLAG)&&!(pushedreg&30)&&stackoffset==-notpopped){
  2018.               /*  Entfernen der Parameter verzoegern  */
  2019.             }else{
  2020.               if(dbout&&!gas){ act_line=p->line; fprintf(f,"\tdebug\t%d\n",act_line);}
  2021.               fprintf(f,"\tadd%s.%s\t#%ld,a7\n",quick[zl2l(p->q2.val.vlong)<=8],strshort[zl2l(p->q2.val.vlong)<32768],zl2l(p->q2.val.vlong));
  2022.               stackoffset+=zl2l(p->q2.val.vlong);
  2023.               notpopped-=zl2l(p->q2.val.vlong);
  2024.             }
  2025.           }
  2026.           continue;
  2027.         }
  2028.         if(c==TEST){
  2029.             /*  ConditionCodes schon gesetzt?   */
  2030.             cc_set=&p->q1;cc_typ=t;
  2031.             comptyp=t;
  2032.             if(cc_set_tst&&t==cc_typ_tst){
  2033.                 struct IC *branch;
  2034.                 if(t&UNSIGNED){
  2035.                     branch=p->next;
  2036.                     while(branch&&(branch->code<BEQ||branch->code>BGT))
  2037.                         branch=branch->next;
  2038.                     if(!branch) continue;
  2039.                     if(branch->code==BLE) branch->code=BEQ;
  2040.                     if(branch->code==BGT) branch->code=BNE;
  2041.                     if(branch->code==BGE) {branch->code=BRA;continue;}
  2042.                     if(branch->code==BLT) {branch->code=NOP;continue;}
  2043.                 }
  2044.                 if(compare_objects(&p->q1,cc_set_tst)&&p->q1.am==cc_set_tst->am&&zleqto(p->q1.val.vlong,cc_set_tst->val.vlong)){
  2045.                     if(DEBUG&512){fprintf(f,"; tst eliminated: cc=");probj2(f,cc_set_tst,t);
  2046.                                   fprintf(f,", q1=");probj2(f,&p->q1,t);fprintf(f,"\n");}
  2047.                     continue;
  2048.                 }
  2049.             }
  2050.             if(g_flags_val[0].l<68020&&isreg(q1)&&p->q1.reg>=1&&p->q1.reg<=8){
  2051.             /*  tst ax gibt es nicht bei <68000 :-( */
  2052.                 if(regavailable(1)){
  2053.                     fprintf(f,"\tmove.%c\t%s,%s\n",x_t[t&NQ],regnames[p->q1.reg],regnames[get_reg(f,1,p)]);
  2054.                 }else{
  2055.                     fprintf(f,"\tcmp.w\t#0,%s\n",regnames[p->q1.reg]);
  2056.                 }
  2057.                 continue;
  2058.             }
  2059.             if((t==DOUBLE||t==FLOAT)&&g_flags_val[1].l<68000){
  2060.             /*  nicht sehr schoen   */
  2061.                 int result=get_reg(f,1,p);
  2062.                 saveregs(f,p);
  2063.                 assign(f,p,&p->q1,0,PUSH,msizetab[t&NQ],t);
  2064.                 if(gas){
  2065.                     fprintf(f,"\t.global\t__ieeetst%c\n\tjbsr\t__ieeetst%c\n\taddq.w\t#%ld,a7\n",x_t[t&NQ],x_t[t&NQ],msizetab[t&NQ]);
  2066.                 }else{
  2067.                     fprintf(f,"\tpublic\t__ieeetst%c\n\tjsr\t__ieeetst%c\n\taddq.w\t#%ld,a7\n",x_t[t&NQ],x_t[t&NQ],msizetab[t&NQ]);
  2068.                 }
  2069.                 stackoffset+=msizetab[t&NQ];
  2070.                 restoreregsa(f,p);
  2071.                 if(result!=9) fprintf(f,"\tmove.l\td0,%s\n",regnames[result]);
  2072.                 fprintf(f,"\ttst.l\t%s\n",regnames[result]);
  2073.                 restoreregsd(f,p);
  2074.                 continue;
  2075.             }
  2076.             if(isreg(q1)&&p->q1.reg>=17){fprintf(f,"\tftst.x\t%s\n",regnames[p->q1.reg]);continue;}
  2077.             fprintf(f,"\t%stst.%c\t",fp,x_t[t&NQ]);probj2(f,&p->q1,t);
  2078.             fprintf(f,"\n");
  2079.             continue;
  2080.         }
  2081.         if(c==ASSIGN||c==PUSH){
  2082.             if(c==ASSIGN&&compare_objects(&p->q1,&p->z)) cc_set=0;
  2083.             if(c==PUSH) dontpop+=zl2l(p->q2.val.vlong);
  2084.             assign(f,p,&p->q1,&p->z,c,zl2l(p->q2.val.vlong),t);
  2085.             continue;
  2086.         }
  2087.         if(c==ADDRESS){
  2088.             int zreg;
  2089.             if(isreg(z)&&p->z.reg>=1&&p->z.reg<=8)
  2090.                 zreg=p->z.reg; else zreg=get_reg(f,0,p);
  2091.             fprintf(f,"\tlea\t");probj2(f,&p->q1,t);
  2092.             fprintf(f,",%s\n",regnames[zreg]);
  2093.             if(!isreg(z)||p->z.reg!=zreg){
  2094.                 move(f,0,zreg,&p->z,0,POINTER);
  2095.             }
  2096.             continue;
  2097.         }
  2098.         if(c==COMPARE){
  2099.             int zreg;
  2100.             comptyp=t;
  2101.             if((p->q1.flags&KONST)||isreg(q2)){
  2102.             /*  evtl. Argumente von cmp und nachfolgendes bcc umdrehen  */
  2103.                 struct IC *n;struct obj m;
  2104.                 n=p->next;
  2105.                 while(n){
  2106.                     if(n->code>=BEQ&&n->code<BRA){
  2107.                         if(!p->z.flags){
  2108.                             if(DEBUG&1) printf("arguments of cmp exchanged\n");
  2109.                             m=p->q1;p->q1=p->q2;p->q2=m;
  2110.                             p->z.flags=1;
  2111.                         }
  2112.                         /*  nachfolgenden Branch umdrehen   */
  2113.                         switch(n->code){
  2114.                             case BGT: n->code=BLT;break;
  2115.                             case BLT: n->code=BGT;break;
  2116.                             case BGE: n->code=BLE;break;
  2117.                             case BLE: n->code=BGE;break;
  2118.                         }
  2119.                         break;
  2120.                     }
  2121.                     if(n->code==FREEREG) n=n->next; else break; /*  compare ohne branch => leerer Block o.ae.   */
  2122.                 }
  2123.             }
  2124.             if(t==FLOAT||t==DOUBLE){
  2125.                 if(g_flags_val[1].l>=68000){
  2126.                     if(isreg(q1)&&p->q1.reg>=17){
  2127.                         zreg=p->q1.reg;
  2128.                     }else{
  2129.                         zreg=get_reg(f,2,p);
  2130.                         move(f,&p->q1,0,0,zreg,t);
  2131.                     }
  2132.                     if(isreg(q2)){fprintf(f,"\tfcmp.x\t%s,%s\n",regnames[p->q2.reg],regnames[zreg]);continue;}
  2133.                     fprintf(f,"\tfcmp.%c\t",x_t[t&NQ]);probj2(f,&p->q2,t);
  2134.                     fprintf(f,",%s\n",regnames[zreg]);
  2135.                     continue;
  2136.                 }else{
  2137.                 /*  nicht sehr schoen   */
  2138.                     int result=get_reg(f,1,p);
  2139.                     saveregs(f,p);
  2140.                     assign(f,p,&p->q2,0,PUSH,msizetab[t&NQ],t);
  2141.                     assign(f,p,&p->q1,0,PUSH,msizetab[t&NQ],t);
  2142.                     if(gas){
  2143.                         fprintf(f,"\t.global\t__ieeecmp%c\n\tjbsr\t__ieeecmp%c\n\tadd.w\t#%ld,a7\n",x_t[t&NQ],x_t[t&NQ],2*msizetab[t&NQ]);
  2144.                     }else{
  2145.                         fprintf(f,"\tpublic\t__ieeecmp%c\n\tjsr\t__ieeecmp%c\n\tadd.w\t#%ld,a7\n",x_t[t&NQ],x_t[t&NQ],2*msizetab[t&NQ]);
  2146.                     }
  2147.                     stackoffset+=2*msizetab[t&NQ];
  2148.                     restoreregsa(f,p);
  2149.                     if(result!=9) fprintf(f,"\tmove.l\td0,%s\n",regnames[result]);
  2150.                     fprintf(f,"\ttst.l\t%s\n",regnames[result]);
  2151.                     restoreregsd(f,p);
  2152.                     continue;
  2153.                 }
  2154.             }
  2155.             if(p->q2.flags&KONST){
  2156.                 fprintf(f,"\tcmp.%c\t",x_t[t&NQ]);probj2(f,&p->q2,t);
  2157.                 fprintf(f,",");probj2(f,&p->q1,t);fprintf(f,"\n");
  2158.                 continue;
  2159.             }
  2160.             if(isreg(q1)){
  2161.                 zreg=p->q1.reg;
  2162.             }else{
  2163.                 zreg=get_reg(f,1,p);    /* hier evtl. auch Adressregister nehmen */
  2164.                 move(f,&p->q1,0,0,zreg,t);
  2165.             }
  2166.             fprintf(f,"\tcmp.%c\t",x_t[t&NQ]);probj2(f,&p->q2,t);
  2167.             fprintf(f,",%s\n",regnames[zreg]);
  2168.             continue;
  2169.         }
  2170.         if(c==ADDI2P||c==SUBIFP){
  2171.             int zreg,r;
  2172.             if(isreg(q1)&&p->q1.reg<=8&&isreg(z)&&p->z.reg<=8&&p->q1.reg!=p->z.reg){
  2173.             /*  q1 und z Adressregister => lea nehmen   */
  2174.                 if(p->q2.flags&KONST){
  2175.                     eval_const(&p->q2.val,t);
  2176.                     if(c==SUBIFP) vlong=zlsub(l2zl(0L),vlong);
  2177.                     if(g_flags_val[0].l>=68020||(zlleq(vlong,l2zl(32767))&&zlleq(l2zl(-32768),vlong))){
  2178.                         fprintf(f,"\tlea\t(%ld,%s),%s\n",zl2l(vlong),regnames[p->q1.reg],regnames[p->z.reg]);
  2179.                         continue;
  2180.                     }
  2181.                 }else if(c==ADDI2P&&isreg(q2)){
  2182.                     fprintf(f,"\tlea\t(%s,%s.%c),%s\n",regnames[p->q1.reg],regnames[p->q2.reg],x_t[t&NQ],regnames[p->z.reg]);
  2183.                     continue;
  2184.                 }
  2185.             }
  2186.             if(compare_objects(&p->q1,&p->z)){
  2187.                 if(p->q2.flags&KONST){
  2188.                     if(c==ADDI2P)
  2189.                         fprintf(f,"\tadd%s.l\t",quick[isquickkonst2(&p->q2.val,t)]);
  2190.                     else
  2191.                         fprintf(f,"\tsub%s.l\t",quick[isquickkonst2(&p->q2.val,t)]);
  2192.                     probj2(f,&p->q2,t);fprintf(f,",");
  2193.                     probj2(f,&p->z,POINTER);fprintf(f,"\n");
  2194.                     continue;
  2195.                 }
  2196.                 if(isreg(q1)&&(x_t[t&NQ]=='l'||p->q1.reg<=8)){
  2197.                     if(c==ADDI2P)
  2198.                         fprintf(f,"\tadd.%c\t",x_t[t&NQ]);
  2199.                     else
  2200.                         fprintf(f,"\tsub.%c\t",x_t[t&NQ]);
  2201.                     probj2(f,&p->q2,t);fprintf(f,",%s\n",regnames[p->z.reg]);
  2202.                     continue;
  2203.                 }
  2204.                 if(isreg(q2)&&p->q2.reg>=1){
  2205.                     r=p->q2.reg;
  2206.                 }else{
  2207.                     r=get_reg(f,1,p);
  2208.                     move(f,&p->q2,0,0,r,t);
  2209.                 }
  2210.                 if(x_t[t&NQ]!='l'&&(!isreg(z)||p->z.reg<1||p->z.reg>8)){
  2211.                 /*  wenn Ziel kein Adressregister, muss short erst auf long */
  2212.                 /*  char darf hier nicht auftreteten und long passt schon   */
  2213.                     if(t&UNSIGNED) fprintf(f,"\tswap\t%s\n\tclr.w\t%s\n\tswap\t%s\n",regnames[r],regnames[r],regnames[r]);
  2214.                      else          fprintf(f,"\text.l\t%s\n",regnames[r]);
  2215.                     t=POINTER;
  2216.                 }
  2217. /*                if(c==ADDI2P)
  2218.                     fprintf(f,"\tadd.%c\t%s,",x_t[t&NQ],regnames[r]);
  2219.                 else
  2220.                     fprintf(f,"\tsub.%c\t%s,",x_t[t&NQ],regnames[r]);
  2221.                 probj2(f,&p->z,t);fprintf(f,"\n");*/
  2222.                 if(c==ADDI2P) add(f,0,r,&p->z,0,t);
  2223.                  else         sub(f,0,r,&p->z,0,t);
  2224.                 continue;
  2225.             }
  2226.             if(isreg(z)&&p->z.reg>=1&&p->z.reg<=16)
  2227.                 zreg=p->z.reg; else zreg=get_reg(f,0,p);
  2228.             /*  Spezialfall, falls Ziel Datenregister und short */
  2229.             /*  nicht schoen, aber auf die Schnelle...          */
  2230.             if(x_t[t&NQ]!='l'&&zreg>8){
  2231.                 move(f,&p->q2,0,0,zreg,t);
  2232.                 if(t&UNSIGNED) fprintf(f,"\tswap\t%s\n\tclr.w\t%s\n\tswap\t%s\n",regnames[zreg],regnames[zreg],regnames[zreg]);
  2233.                  else          fprintf(f,"\text.l\t%s\n",regnames[zreg]);
  2234.                 if(c==SUBIFP) fprintf(f,"\tneg.l\t%s\n",regnames[zreg]);
  2235.                 add(f,&p->q1,0,0,zreg,POINTER);
  2236.                 if(!isreg(z)||p->z.reg!=zreg)
  2237.                     move(f,0,zreg,&p->z,0,POINTER);
  2238.                 continue;
  2239.             }
  2240.             if(!isreg(q1)||p->q1.reg!=zreg){
  2241.                 move(f,&p->q1,0,0,zreg,POINTER);
  2242.             }
  2243.             if(c==ADDI2P) add(f,&p->q2,0,0,zreg,t);
  2244.              else         sub(f,&p->q2,0,0,zreg,t);
  2245.             if(!isreg(z)||p->z.reg!=zreg){
  2246.                 move(f,0,zreg,&p->z,0,POINTER);
  2247.             }
  2248.             continue;
  2249.         }
  2250.         if((c>=OR&&c<=AND)||(c>=LSHIFT&&c<=MOD)){
  2251.             int zreg,q1reg,q2reg;
  2252.             if((p->q2.flags&KONST)&&
  2253.                (!(p->q1.flags®)||!(p->z.flags®)||p->q1.reg!=p->z.reg)&&
  2254.                (!(p->q1.flags&VAR)||!(p->z.flags&VAR)||p->q1.v!=p->z.v)&&
  2255.                ((c>=OR&&c<=AND)||c==ADD||c==MULT)){
  2256.                 struct obj o;
  2257.                 if(c==MULT){
  2258.                     eval_const(&p->q2.val,t);
  2259.                     if(zlleq(l2zl(0L),vlong)&&zulleq(ul2zul(0UL),vulong)&&!pof2(vulong)){
  2260.                         o=p->q1;p->q1=p->q2;p->q2=o;
  2261.                     }
  2262.                 }else{
  2263.                     o=p->q1;p->q1=p->q2;p->q2=o;
  2264.                 }
  2265.             }
  2266.             if(t==FLOAT||t==DOUBLE){
  2267.                 if(g_flags_val[1].l>=68000){
  2268.                     if(isreg(z)&&p->z.reg>=17) zreg=p->z.reg;
  2269.                         else zreg=get_reg(f,2,p);
  2270.                     if(!isreg(q1)||p->q1.reg!=p->z.reg)
  2271.                         move(f,&p->q1,0,0,zreg,t);
  2272.                     fprintf(f,"\tf%s.",ename[c]);
  2273.                     if(isreg(q2)) fprintf(f,"x\t");
  2274.                         else      fprintf(f,"%c\t",x_t[t&NQ]);
  2275.                     probj2(f,&p->q2,t);
  2276.                     fprintf(f,",%s\n",regnames[zreg]);
  2277.                     if(!isreg(z)||p->z.reg!=zreg){
  2278.                         move(f,0,zreg,&p->z,0,t);
  2279.                     }
  2280.                     continue;
  2281.                 }else{
  2282.                     saveregs(f,p);
  2283.                     assign(f,p,&p->q2,0,PUSH,msizetab[t&NQ],t);
  2284.                     assign(f,p,&p->q1,0,PUSH,msizetab[t&NQ],t);
  2285.                     if(gas){
  2286.                         fprintf(f,"\t.global\t__ieee%s%c\n\tjbsr\t__ieee%s%c\n\tadd.w\t#%ld,a7\n",ename[c],x_t[t&NQ],ename[c],x_t[t&NQ],2*msizetab[t&NQ]);
  2287.                     }else{
  2288.                         fprintf(f,"\tpublic\t__ieee%s%c\n\tjsr\t__ieee%s%c\n\tadd.w\t#%ld,a7\n",ename[c],x_t[t&NQ],ename[c],x_t[t&NQ],2*msizetab[t&NQ]);
  2289.                     }
  2290.                     stackoffset+=2*msizetab[t&NQ];
  2291.                     restoreregsa(f,p);
  2292.                     if(t==DOUBLE){
  2293.                         fprintf(f,"\tmovem.l\td0/d1,");
  2294.                         probj2(f,&p->z,t);fprintf(f,"\n");
  2295.                     }else move(f,0,9,&p->z,0,t);
  2296.                     restoreregsd(f,p);
  2297.                     continue;
  2298.                 }
  2299.             }
  2300.             if((c==MULT||c==DIV||(c==MOD&&(p->typf&UNSIGNED)))&&(p->q2.flags&KONST)){
  2301.             /*  ersetzt mul etc. mit Zweierpotenzen     */
  2302.             /*  hier evtl. noch Fehler                  */
  2303.                 long ln;
  2304.                 eval_const(&p->q2.val,t);
  2305.                 if(zlleq(l2zl(0L),vlong)&&zulleq(ul2zul(0UL),vulong)){
  2306.                     if(ln=pof2(vulong)){
  2307.                         if(c==MOD){
  2308.                             vlong=zlsub(vlong,l2zl(1L));
  2309.                             p->code=AND;
  2310.                         }else{
  2311.                             vlong=l2zl(ln-1);
  2312.                             if(c==DIV) p->code=RSHIFT; else p->code=LSHIFT;
  2313.                         }
  2314.                         c=p->code;
  2315.                         if((t&NU)==CHAR) p->q2.val.vchar=zl2zc(vlong);
  2316.                         if((t&NU)==SHORT) p->q2.val.vshort=zl2zs(vlong);
  2317.                         if((t&NU)==INT) p->q2.val.vint=zl2zi(vlong);
  2318.                         if((t&NU)==LONG) p->q2.val.vlong=vlong;
  2319.                         vulong=zl2zul(vlong);
  2320.                         if((t&NU)==(UNSIGNED|CHAR)) p->q2.val.vuchar=zul2zuc(vulong);
  2321.                         if((t&NU)==(UNSIGNED|SHORT)) p->q2.val.vushort=zul2zus(vulong);
  2322.                         if((t&NU)==(UNSIGNED|INT))  p->q2.val.vuint=zul2zui(vulong);
  2323.                         if((t&NU)==(UNSIGNED|LONG)) p->q2.val.vulong=vulong;
  2324.                     }
  2325.                 }
  2326.             }
  2327.             if(c==DIV||c==MOD){
  2328.                 if(x_t[t&NQ]=='l'&&g_flags_val[0].l<68020){
  2329.                 /*  das hier ist auch nicht allzu schoen  */
  2330.                     char *fname;
  2331.                     cc_set=0;   /*  Library-Funktionen setzen cc nicht immer */
  2332.                     saveregs(f,p);
  2333.                     fprintf(f,"\tmove.l\t"); probj2(f,&p->q2,t);
  2334.                     fprintf(f,",-(a7)\n");
  2335.                     stackoffset-=4;
  2336.                     fprintf(f,"\tmove.l\t"); probj2(f,&p->q1,t);
  2337.                     fprintf(f,",-(a7)\n");
  2338.                     stackoffset-=4;
  2339.                     if(c==DIV){
  2340.                         if(t&UNSIGNED) fname="divu"; else fname="divs";
  2341.                     }else{
  2342.                         if(t&UNSIGNED) fname="modu"; else fname="mods";
  2343.                     }
  2344.                     if(gas){
  2345.                         fprintf(f,"\t.global\t__l%s\n\tjbsr\t__l%s\n",fname,fname);
  2346.                     }else{
  2347.                         fprintf(f,"\tpublic\t__l%s\n\tjsr\t__l%s\n",fname,fname);
  2348.                     }
  2349.                     fprintf(f,"\taddq.w\t#8,a7\n");
  2350.                     stackoffset+=8;
  2351.                     restoreregsa(f,p);
  2352.                     move(f,0,9,&p->z,0,t);
  2353.                     restoreregsd(f,p);
  2354.                     continue;
  2355.                 }
  2356.  
  2357.             }
  2358.             /*  hier die zweite Alternative mit isreg() schreiben?  */
  2359.             if(compare_objects(&p->q2,&p->z)){
  2360.                 struct obj m;
  2361.                 if((c>=OR&&c<=AND)||c==ADD||c==SUB){
  2362.                     if(c!=SUB){
  2363.                         m=p->q1;p->q1=p->q2;p->q2=m;
  2364.                     }else{
  2365.                         if(isreg(q2)&&p->q2.reg>=9&&p->q2.reg<=16){
  2366.                             m=p->q1;p->q1=p->q2;p->q2=m;
  2367.                             c=ADD;
  2368.                             fprintf(f,"\tneg.%c\t",x_t[t&NQ]);
  2369.                             probj2(f,&p->q1,t);fprintf(f,"\n");
  2370.                         }
  2371.                     }
  2372.                 }
  2373.             }
  2374.             if(compare_objects(&p->q1,&p->z)){
  2375.                 if((c>=OR&&c<=AND)||c==ADD||c==SUB){
  2376.                     int r;
  2377.                     if(p->q2.flags&KONST){
  2378.                         if(c==ADD) {add(f,&p->q2,0,&p->z,0,t);continue;}
  2379.                         if(c==SUB) {sub(f,&p->q2,0,&p->z,0,t);continue;}
  2380.                         fprintf(f,"\t%s.%c\t",ename[c],x_t[t&NQ]);
  2381.                         probj2(f,&p->q2,t);fprintf(f,",");
  2382.                         probj2(f,&p->z,t);fprintf(f,"\n");
  2383.                         continue;
  2384.                     }
  2385.                     if(!isreg(z)){
  2386.                         if(isreg(q2)&&p->q2.reg>=9&&p->q2.reg<=16)
  2387.                             r=p->q2.reg; else r=get_reg(f,1,p);
  2388.                         if(!isreg(q2)||p->q2.reg!=r){
  2389.                             move(f,&p->q2,0,0,r,t);
  2390.                         }
  2391.                         fprintf(f,"\t%s.%c\t%s,",ename[c],x_t[t&NQ],regnames[r]);
  2392.                         probj2(f,&p->z,t);fprintf(f,"\n");
  2393.                         continue;
  2394.                     }
  2395.                 }
  2396.             }
  2397.             /*  bei xor oder asl (ausser 0<=const<=8) muss q2 in Register   */
  2398.             if(isreg(q2)&&p->q2.reg>=9&&p->q2.reg<=16){
  2399.                 q2reg=p->q2.reg;
  2400.             }else{
  2401.                 if(c==LSHIFT||c==RSHIFT||c==XOR){
  2402.                     eval_const(&p->q2.val,t);
  2403.                     if(c==XOR||!(p->q2.flags&KONST)||!isquickkonst2(&p->q2.val,t)){
  2404.                         q2reg=get_reg(f,1,p);
  2405.                         move(f,&p->q2,0,0,q2reg,t);
  2406.                     }else q2reg=0;
  2407.                 }else{
  2408.                     q2reg=0;
  2409.                 }
  2410.             }
  2411.             if(c==MOD){
  2412.                 int modreg;
  2413.                 modreg=get_reg(f,1,p);
  2414.                 if(isreg(z)&&p->z.reg>=9&&p->z.reg<=16&&p->z.reg!=q2reg)
  2415.                     zreg=p->z.reg; else zreg=get_reg(f,1,p);
  2416.                 move(f,&p->q1,0,0,modreg,t);
  2417.                 if(0 /*g_flags_val[0].l==68060*/){
  2418.                 /*  div?l.l wird da emuliert?   */
  2419.                     fprintf(f,"\tsmi\t%s\n\textb.l\t%s\n",regnames[zreg],regnames[zreg]);
  2420.                     if(t&UNSIGNED) fprintf(f,"\tdivu.%c\t",x_t[t&NQ]); else fprintf(f,"\tdivs.%c\t",x_t[t&NQ]);
  2421.                 }else{
  2422.                     if(t&UNSIGNED) fprintf(f,"\tdivul.%c\t",x_t[t&NQ]); else fprintf(f,"\tdivsl.%c\t",x_t[t&NQ]);
  2423.                 }
  2424.                 probj2(f,&p->q2,t);
  2425.                 fprintf(f,",%s:%s\n",regnames[zreg],regnames[modreg]);
  2426.                 move(f,0,zreg,&p->z,0,t);
  2427.                 cc_set=0;
  2428.                 continue;
  2429.             }
  2430.             if(isreg(z)&&p->z.reg>=9&&p->z.reg<=16&&p->z.reg!=q2reg)
  2431.                 zreg=p->z.reg; else zreg=get_reg(f,1,p);
  2432.             if(isreg(q1)&&p->q1.reg>=9&&p->q1.reg<=16)
  2433.                 q1reg=p->q1.reg; else q1reg=0;
  2434.             if(q1reg!=zreg){
  2435.                 move(f,&p->q1,0,0,zreg,t);
  2436.             }
  2437.             if(c!=MULT&&c!=DIV&&c!=MOD&&c!=ADD&&c!=SUB){
  2438.                 if(c==RSHIFT&&!(t&UNSIGNED)) fprintf(f,"\tasr.%c\t",x_t[t&NQ]);
  2439.                  else fprintf(f,"\t%s.%c\t",ename[c],x_t[t&NQ]);
  2440.                 if(q2reg) fprintf(f,"%s",regnames[q2reg]); else probj2(f,&p->q2,t);
  2441.                 fprintf(f,",%s\n",regnames[zreg]);
  2442.             }else{
  2443.                 if(c==ADD) add(f,&p->q2,q2reg,0,zreg,t);
  2444.                 if(c==SUB) sub(f,&p->q2,q2reg,0,zreg,t);
  2445.                 if(c==MULT||c==DIV||c==MOD) mult(f,&p->q2,q2reg,0,zreg,t,c,p);
  2446.             }
  2447.             if((!isreg(z)||p->z.reg!=zreg)){
  2448.                 move(f,0,zreg,&p->z,0,t);
  2449.             }
  2450.             continue;
  2451.         }
  2452.         ierror(0);
  2453.     }
  2454.     if(notpopped){
  2455.         fprintf(f,"\tadd%s.%s\t#%ld,a7\n",quick[notpopped<=8],strshort[notpopped<32768],notpopped);
  2456.         stackoffset+=notpopped;notpopped=0;
  2457.     }
  2458.     function_bottom(f,v,zl2l(offset));
  2459.     if(pushflag){   /*  Speicher fuer pushlabel generieren - leider im cseg */
  2460.         if(gas){
  2461.             fprintf(f,"\t.lcomm\tl%d,4\n",pushlabel);
  2462.         }else{
  2463.             fprintf(f,"\tcnop\t0,4\nl%d\n\tds.b\t4\n",pushlabel);
  2464.         }
  2465.         pushflag=0;
  2466.     }
  2467. }
  2468.  
  2469. int shortcut(int code,int typ)
  2470. {
  2471.     if(code==COMPARE) return(1);
  2472.     return(0);
  2473. }
  2474.  
  2475. void cleanup_cg(FILE *f)
  2476. {
  2477.     return;
  2478. }
  2479.  
  2480.